首页 > 解决方案 > 为什么在运行没有 cmake 编译的示例程序时会出现分段错误?(MSYS2, Mingw-w64)

问题描述

简而言之

cmake 的 makefile 网络与对最终可执行文件产生影响的简单编译和链接有何不同?

我正在尝试使用子弹物理库(bullet3-2.83.7)https://github.com/bulletphysics/bullet3
我用 Mingw-w64 在 MSYS2 中编译了这个库,几乎没有警告。
之后我可以毫无问题地运行示例程序,特别是 ExampleBrowser 和 HelloWorld。
我一直在尝试仅使用 Makefile 将 HelloWorld 源代码合并到测试项目中,但是每当在可执行文件中调用 dynamicsWorld 时,我都会收到 SIGSEGV 错误。SEGFAULT 出现在行dynamicsWorld->AddRigidBody(body);或如果那些被注释掉dynamicsWorld->stepSimulation
这发生在使用 makefile 编译的确切示例源文件中(源未修改)。

gdb 告诉我这个

main (argc=1, argv=0x5f4eb0) at main.cpp:78
78                      dynamicsWorld->addRigidBody(body);
(gdb) step
0x0000000000002000 in ?? ()
(gdb) step
Cannot find bounds of current function
(gdb) bt full
#0  0x0000000000002000 in ?? ()
No symbol table info available.
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

我不知道如何处理这些信息。我假设/希望我只是缺少编译器或链接器标志?我原来的 Makefile 基于http://make.mad-scientist.net/papers/advanced-auto-dependency-generation
是一团糟。我认为通过添加库和包含目录在示例代码中使用现有的makefile就足够了-lBulletDynamics_Debug -lBulletCollision_Debug -lLinearMath_Debug

我还尝试了一个简化的 Makefile,其中包含我发现从 bullet3/examples/HelloWorld grepping CMake 目录的命令和标志。

我的 PATH 环境变量是干净的,LD_LIBRARY_PATH 中没有任何内容(在 MSYS 中:echo $PATH)

MSYS2 Mingw-w64
gcc 10.1.0
MSYS 20180531msys64 ? pacman updated a lot of things
CMake 3.17.3
GNU Make 4.3

生成文件

CXX_DEFINES = -DUSE_GRAPHICAL_BENCHMARK -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS 

CXX_INCLUDES = -I"C:\lib64\include\bullet3"
CXX_FLAGS = -g -fpermissive -D_DEBUG 

.PHONY: all
all:
    g++.exe $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -o main.obj -c main.cpp
    ar cr main.a main.obj
    g++.exe $(CXX_FLAGS) -Wl,--whole-archive main.a -Wl,--no-whole-archive -o bulletTest.exe -Wl,--major-image-version,0,--minor-image-version,0 libBulletDynamics_Debug.a libBulletCollision_Debug.a libLinearMath_Debug.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

# -L"C:\lib64\lib" 

.PHONY: run
run:
    gdb -ex run bulletTest.exe -ex "bt full" -ex quit --batch

.PHONY: clean
clean:
    rm -f ./bulletTest.exe ./main.obj ./main.a

在 MSYS2 中构建子弹物理库

在 bullet3-2.83.7 目录中(tar.gz 来自https://github.com/bulletphysics/bullet3/releases

mkdir build-mingw64
cd build-mingw64
cmake -G "MSYS Makefiles" \
    -DBUILD_SHARED_LIBS=0 \
    -DBUILD_EXTRAS=1 \
    -DINSTALL_LIBS=0 \
    -DUSE_GLUT=1 \
    -DCMAKE_CXX_FLAGS_DEBUG="-fpermissive -g" \
    -DINSTALL_EXTRA_LIBS=0 \
    -DCMAKE_BUILD_TYPE=Debug ..
make -j

标签: gccmakefilecmakemingw-w64msys2

解决方案


我遇到了同样的问题。在我的情况下,这是因为 Bullet 是使用 USE_DOUBLE_PRECISION 编译的,因此将以下内容添加到我的可执行文件的 cmakelists 为我解决了这个问题:

target_compile_options(<target_name> BEFORE PUBLIC -DBT_USE_DOUBLE_PRECISION)

推荐阅读