c ++ vtk:hello world仅在发布时在运行时失败
Posted
技术标签:
【中文标题】c ++ vtk:hello world仅在发布时在运行时失败【英文标题】:c++ vtk: hello world fails at run time only in Release 【发布时间】:2017-03-27 10:38:45 【问题描述】:我将 hello world 代码复制到我的主 c++ 中,希望能够一点一点地修改它,以便慢慢创建我的渲染。我能够在发布和调试模式下编译它。但是当我运行它时,它在调试中工作并且在发布时失败。我得到一个分段错误。
我的设置是 netbeans 中的一个 cmake 项目。我的 CMakeList.txt 看起来像这样:
cmake_minimum_required(VERSION 3.6)
project(uvlm)
set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES
... hidden for clarity ...)
include_directories(.
$EIGEN_LIBRARY_PATH
$GITREPO_PATH/hydros-mathlibrary/HydrosTools/UsefullCppFcts
$GITREPO_PATH/hydros-mathlibrary/HydrosMathLibraryCode/Include/
)
if(CMAKE_BUILD_TYPE MATCHES "Debug")
set(EXECUTABLE_OUTPUT_PATH $GITREPO_PATH/hydros-uvlm/uvlm/Debug/bin)
set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS $CMAKE_CXX_FLAGS_DEBUG -std=c++14 -D__LINUX__ ")
elseif(CMAKE_BUILD_TYPE MATCHES "Profiling")
set(EXECUTABLE_OUTPUT_PATH $GITREPO_PATH/hydros-uvlm/uvlm/Profiling/bin)
set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS $CMAKE_CXX_FLAGS_RELEASE -std=c++14 -D__LINUX__ ")
else()
set(EXECUTABLE_OUTPUT_PATH $GITREPO_PATH/hydros-uvlm/uvlm/Release/bin)
set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS $CMAKE_CXX_FLAGS_RELEASE -std=c++14 -D__LINUX__ ")
endif()
# DEBUG LIBRARIES
find_library(GTE_DEBUG_CXX_LIBRARY NAMES libgtengine.a HINTS $GITREPO_PATH/hydros-mathlibrary/HydrosMathLibraryCode/lib/Debug)
find_library(USEFULFCTS_DEBUG_CXX_LIBRARY NAMES libusefulfcts.a HINTS $GITREPO_PATH/hydros-mathlibrary/HydrosTools/UsefullCppFcts/lib/Debug)
# RELEASE LIBRARIES
find_library(GTE_RELEASE_CXX_LIBRARY NAMES libgtengine.a HINTS $GITREPO_PATH/hydros-mathlibrary/HydrosMathLibraryCode/lib/Release)
find_library(USEFULFCTS_RELEASE_CXX_LIBRARY NAMES libusefulfcts.a HINTS $GITREPO_PATH/hydros-mathlibrary/HydrosTools/UsefullCppFcts/lib/Release)
FIND_PACKAGE( OpenMP)
if(OPENMP_FOUND)
message("OPENMP FOUND")
set(CMAKE_C_FLAGS "$CMAKE_C_FLAGS $OpenMP_C_FLAGS")
set(CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS $OpenMP_CXX_FLAGS")
set(CMAKE_EXE_LINKER_FLAGS "$CMAKE_EXE_LINKER_FLAGS $OpenMP_EXE_LINKER_FLAGS")
endif()
include_directories(SYSTEM $OpenMP_INCLUDE_PATH)
find_package(VTK REQUIRED)
include($VTK_USE_FILE)
add_executable(uvlm $SOURCE_FILES)
target_link_libraries(uvlm debug $GTE_DEBUG_CXX_LIBRARY $USEFULFCTS_DEBUG_CXX_LIBRARY $VTK_LIBRARIES optimized $GTE_RELEASE_CXX_LIBRARY $USEFULFCTS_RELEASE_CXX_LIBRARY $OpenMP_CXX_LIBRARIES $VTK_LIBRARIES)
我的 cmake 命令行有这样的参数:
$CMAKE -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=$IDE_CC -DCMAKE_CXX_COMPILER=$IDE_CXX -DCMAKE_C_FLAGS_RELEASE="-O3 -DEIGEN_NO_DEBUG -march=native -mfpmath=sse -funroll-loops" -DCMAKE_CXX_FLAGS_RELEASE=" -O3 -mfpmath=sse -funroll-loops -DEIGEN_NO_DEBUG " -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DEIGEN_LIBRARY_PATH="HIDDENPATH" -DGITREPO_PATH="HIDDENPATH" .
我在 Fedora 25 上使用 dnf 安装了 vtk:vtk-devel-6.3.0-11.fc25.x86_64
我运行的代码如下:
void vtkRenderingTest(std::string fileName, bool mbdynInfiniteLoop)
// This creates a polygonal cylinder model with eight circumferential facets
// (i.e, in practice an octagonal prism).
vtkSmartPointer<vtkCylinderSource> cylinder =
vtkSmartPointer<vtkCylinderSource>::New();
cylinder->SetResolution(8);
// The mapper is responsible for pushing the geometry into the graphics library.
// It may also do color mapping, if scalars or other attributes are defined.
vtkSmartPointer<vtkPolyDataMapper> cylinderMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
// The actor is a grouping mechanism: besides the geometry (mapper), it
// also has a property, transformation matrix, and/or texture map.
// Here we set its color and rotate it around the X and Y axes.
vtkSmartPointer<vtkActor> cylinderActor =
vtkSmartPointer<vtkActor>::New();
cylinderActor->SetMapper(cylinderMapper);
cylinderActor->GetProperty()->SetColor(1.0000, 0.3882, 0.2784);
cylinderActor->RotateX(30.0);
cylinderActor->RotateY(-45.0);
// The renderer generates the image
// which is then displayed on the render window.
// It can be thought of as a scene to which the actor is added
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(cylinderActor);
renderer->SetBackground(0.1, 0.2, 0.4);
// Zoom in a little by accessing the camera and invoking its "Zoom" method.
renderer->ResetCamera();
renderer->GetActiveCamera()->Zoom(1.5);
// The render window is the actual GUI window
// that appears on the computer screen
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->SetSize(200, 200);
renderWindow->AddRenderer(renderer);
// The render window interactor captures mouse events
// and will perform appropriate camera or actor manipulation
// depending on the nature of the events.
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
// This starts the event loop and as a side effect causes an initial render.
renderWindowInteractor->Start();
int main(int argc, char* argv[])
try
// put the file name in the run property of the configurations (Release and Debug)
bool mbdynInfiniteLoop = false;
// if (argc > 2) if (argv[2] == "true") mbdynInfiniteLoop = true;
// loadsEval(argv[1], mbdynInfiniteLoop);
vtkRenderingTest("AAAA", true);
return 0;
catch (std::string &e)
std::cout << "############### Error #####################\n\n";
std::cout << e << std::endl;
std::cout << "\n###########################################\n\n";
catch (hyd::HydExceptions &e)
std::cout << "############### Error #####################\n\n";
std::cout << e.errMessage << std::endl;
std::cout << "\n###########################################\n\n";
请记住,它在调试模式下可以完美运行。
冲突的行是GUI的开头,即renderWindowInteractor->Start();
我尝试将调试 cmake 命令复制到发行版,但没有成功。一种我无法发现的隐藏行为在这里起作用!
编辑: 这是您建议查看的输出。这似乎是一个VTK问题? `
==3082== Process terminating with default action of signal 11 (SIGSEGV)
==3082== Access not within mapped region at address 0x0
==3082== at 0x1FAD435F: rawmemchr (in /usr/lib64/libc-2.24.so)
==3082== by 0x1FABC831: _IO_str_init_static_internal (in /usr/lib64/libc-2.24.so)
==3082== by 0x1FAAE7E6: vsscanf (in /usr/lib64/libc-2.24.so)
==3082== by 0x1FAA8A26: sscanf (in /usr/lib64/libc-2.24.so)
==3082== by 0x143292B3: vtkOpenGLExtensionManager::ReadOpenGLExtensions() (in /usr/lib64/vtk/libvtkRenderingOpenGL.so.1)
==3082== by 0x143283CD: vtkOpenGLExtensionManager::Update() (in /usr/lib64/vtk/libvtkRenderingOpenGL.so.1)
==3082== by 0x14323BA3: vtkOpenGLExtensionManager::ExtensionSupported(char const*) (in /usr/lib64/vtk/libvtkRenderingOpenGL.so.1)
==3082== by 0x14371259: vtkOpenGLRenderWindow::OpenGLInitContext() (in /usr/lib64/vtk/libvtkRenderingOpenGL.so.1)
==3082== by 0x1436FBCC: vtkOpenGLRenderWindow::OpenGLInit() (in /usr/lib64/vtk/libvtkRenderingOpenGL.so.1)
==3082== by 0x1444238C: vtkXOpenGLRenderWindow::Start() (in /usr/lib64/vtk/libvtkRenderingOpenGL.so.1)
==3082== by 0x144377BF: vtkXRenderWindowInteractor::Initialize() (in /usr/lib64/vtk/libvtkRenderingOpenGL.so.1)
==3082== by 0x1B2175A2: vtkRenderWindowInteractor::Start() (in /usr/lib64/vtk/libvtkRenderingCore.so.1)
==3082== If you believe this happened as a result of a stack
==3082== overflow in your program's main thread (unlikely but
==3082== possible), you can try to increase the size of the
==3082== main thread stack using the --main-stacksize= flag.
==3082== The main thread stack size used in this run was 8388608.
`
【问题讨论】:
如果您使用的是 linux,那么您应该能够在 valgrind 之类的工具下运行示例代码,该工具应该会指示您是否遇到了任何内存分配问题。这将指示读取/写入未分配/释放的内存,这是SEGV
最常见的触发器。
@Petesh:我做到了,并在问题中提供了结果。谢谢
看the vtk source好像是glGetString(GL_VERSION)
返回一个空指针造成的,一般是没有初始化open GL造成的。 this question 会触发同样的问题吗?如果是这样,那么您可能需要在尝试运行代码以解决该问题之前手动创建一个 openGL 上下文。
好吧,我确实尝试运行您所指的问题。我对 cmake 找不到的 glut 库有问题(未找到 GLUT_Xmu_LIBRARY)。我记得我正在使用运行 Wayland 的 Fedora 25 机器。尽管如此,我怎么能相信 vtk 我们处于调试模式,因为在调试版本中一切正常?
【参考方案1】:
对 CMakeList.txt 文件的以下修改使其运行。这是一个解决方案,但没有解释原因。如果有人可以详细说明为什么这是一个解决方案,请这样做。
我不得不改变链接库的方式。因此我删除了该行
target_link_libraries(uvlm debug $GTE_DEBUG_CXX_LIBRARY $USEFULFCTS_DEBUG_CXX_LIBRARY $VTK_LIBRARIES optimized $GTE_RELEASE_CXX_LIBRARY $USEFULFCTS_RELEASE_CXX_LIBRARY $OpenMP_CXX_LIBRARIES $VTK_LIBRARIES)
改成
if(CMAKE_BUILD_TYPE MATCHES "Debug")
target_link_libraries(uvlm $GTE_DEBUG_CXX_LIBRARY $USEFULFCTS_DEBUG_CXX_LIBRARY $VTK_LIBRARIES)
else()
target_link_libraries(uvlm $GTE_RELEASE_CXX_LIBRARY $USEFULFCTS_RELEASE_CXX_LIBRARY $VTK_LIBRARIES)
endif()
【讨论】:
以上是关于c ++ vtk:hello world仅在发布时在运行时失败的主要内容,如果未能解决你的问题,请参考以下文章
C++“Hello World.exe”崩溃 - “Hello World.exe 已停止工作。”在命令提示符中使用时
sbt 在运行 Spark hello world 代码时出错?
Malwarebytes 为基本 C#“Hello World!”提供木马警告程序