首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调试符号不包含在gcc编译的C++中

调试符号不包含在gcc编译的C++中
EN

Stack Overflow用户
提问于 2019-06-20 22:37:10
回答 1查看 1.1K关注 0票数 4

我正在用C++构建一个在Python中使用的模块。我的流程分为三个步骤:我将各个C++源代码编译成对象,创建库,然后运行setup.py脚本来编译.pyx->.cpp->.so,同时引用我刚刚创建的库。

我知道我可以用Cython setup.py一步完成所有的事情,这就是我曾经做过的事情。将其分成多个步骤的原因是我想让C++代码自己演化,在这种情况下,我将只使用Cython/python中的编译后的库。

因此,当没有bug时,这个流工作得很好。问题是我试图找到一个段错误的来源,所以我想得到调试符号,这样我就可以运行gdb (我在OSX10.14上安装了gdb,这很痛苦,但它很有效)。

我有一个makefile,它执行以下操作。

步骤1:编译单个C++源文件

所有的文件都是用最小标志编译的,但是-g是存在的:

代码语言:javascript
复制
gcc -mmacosx-version-min=10.7 -stdlib=libc++ -std=c++14 -c -g -O0 -I ./csrc -o /Users/colinww/system-model/build/data_buffer.o csrc/data_buffer.cpp

我认为即使在这里也有一个问题:当我执行nm -pa data_buffer.o时,我看不到调试符号。此外,我还得到了:

代码语言:javascript
复制
(base) cmac-2:system-model colinww$ dsymutil build/data_buffer.o
warning: no debug symbols in executable (-arch x86_64)

步骤2:编译cython源代码

makefile包含以下代码行

代码语言:javascript
复制
cd $(CSRC_DIR) && CC=$(CC) CXX=$(CXX) python3 setup_csrc.py build_ext --build-lib $(BUILD)

setup.py的相关部分包括

代码语言:javascript
复制
....
....
....
compile_args = ['-stdlib=libc++', '-std=c++14', '-O0', '-g']
link_args = ['-stdlib=libc++', '-g']
....
....
....
      Extension("circbuf",
                ["circbuf.pyx"],
                language="c++",
                libraries=["cpysim"],
                include_dirs = ['../build'],
                library_dirs=['../build'],
                extra_compile_args=compile_args,
                extra_link_args=link_args),
....
....
....
ext = cythonize(extensions,
                gdb_debug=True,
                compiler_directives={'language_level': '3'})

setup(ext_modules=ext,
      cmdclass={'build_ext': build_ext},
      include_dirs=[np.get_include()])

当它运行时,它会生成一堆编译/链接命令,比如

代码语言:javascript
复制
gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/colinww/anaconda3/include -arch x86_64 -I/Users/colinww/anaconda3/include -arch x86_64 -I. -I../build -I/Users/colinww/anaconda3/lib/python3.7/site-packages/numpy/core/include -I/Users/colinww/anaconda3/include/python3.7m -c circbuf.cpp -o build/temp.macosx-10.7-x86_64-3.7/circbuf.o -stdlib=libc++ -std=c++14 -O0 -g

代码语言:javascript
复制
g++ -bundle -undefined dynamic_lookup -L/Users/colinww/anaconda3/lib -arch x86_64 -L/Users/colinww/anaconda3/lib -arch x86_64 -arch x86_64 build/temp.macosx-10.7-x86_64-3.7/circbuf.o -L../build -lcpysim -o /Users/colinww/system-model/build/circbuf.cpython-37m-darwin.so -stdlib=libc++ -g

在这两个命令中,都有-g标志。

步骤3:运行调试器

最后,我使用gdb运行我的程序

代码语言:javascript
复制
(base) cmac-2:sim colinww$ gdb python3
(gdb) run system_sim.py

它输出了大量与系统文件相关的东西(似乎是无关的),最后运行我的程序,当它出现段错误时:

代码语言:javascript
复制
Thread 2 received signal SIGSEGV, Segmentation fault.
0x0000000a4585469e in cpysim::DataBuffer<double>::Write(long, long, double) () from /Users/colinww/system-model/build/circbuf.cpython-37m-darwin.so
(gdb) info local
No symbol table info available.
(gdb) where
#0  0x0000000a4585469e in cpysim::DataBuffer<double>::Write(long, long, double) () from /Users/colinww/system-model/build/circbuf.cpython-37m-darwin.so
#1  0x0000000a458d6276 in cpysim::ChannelFilter::Filter(long, long, long) () from /Users/colinww/system-model/build/chfilt.cpython-37m-darwin.so
#2  0x0000000a458b0d29 in __pyx_pf_6chfilt_6ChFilt_4filter(__pyx_obj_6chfilt_ChFilt*, long, long, long) () from /Users/colinww/system-model/build/chfilt.cpython-37m-darwin.so
#3  0x0000000a458b0144 in __pyx_pw_6chfilt_6ChFilt_5filter(_object*, _object*, _object*) () from /Users/colinww/system-model/build/chfilt.cpython-37m-darwin.so
#4  0x000000010002f1b8 in _PyMethodDef_RawFastCallKeywords ()
#5  0x000000010003be64 in _PyMethodDescr_FastCallKeywords ()

正如我上面提到的,我认为问题从最初的编译步骤开始。这与cython无关,我只是从命令行调用gcc,传递-g标志。

代码语言:javascript
复制
(base) cmac-2:system-model colinww$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

感谢您的帮助,谢谢!

更新

我删除了gcc标签,并将其更改为clang。因此,我想我现在很困惑,如果苹果用别名gcc来敲钟,这不是意味着在“那种模式”下,它应该表现得像gcc一样(而且,暗示,有人肯定是这样的)。

更新2

因此,我永远不能让调试符号出现在调试器中,我不得不求助于许多有趣的if-printf语句,但问题是索引变量变得未定义。所以感谢所有的建议,但问题或多或少已经解决了(直到下一次)。谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-28 08:17:01

macOS链接器不会像其他Unixen链接器那样将调试信息链接到最终的二进制文件中。相反,它将调试信息保留在.o文件中,并将“调试映射”写入二进制文件,告诉调试器如何查找和链接从.o文件读取的调试信息。当您剥离二进制文件时,调试映射将被剥离。

因此,您必须确保在最后一个链接之后不会移动或删除.o文件,并且在调试之前不会剥离正在调试的二进制文件。

您可以通过执行以下操作来检查调试映射是否存在:

代码语言:javascript
复制
$ nm -ap <PATH_TO_BINARY> | grep OSO

您应该看到如下所示的输出:

000000005d152f51 - 03 0001 OSO /Path/To/Build/Folder/SomeFile.o

如果您没有看到可执行文件可能被剥离了。如果.o文件不在附近,那么就是有人比他们应该清理的更早地清理了您的构建文件夹。

我也不知道gdb是否知道如何读取macOS上的调试映射。如果存在调试映射条目和.o文件,您可以尝试lldb,看看是否可以找到调试信息。如果可以,那么这很可能是gdb-on-macOS的问题。如果OSO和.o文件都存在,那么我猜不到的地方出了问题,也许值得向http://bugreporter.apple.com提交一个bug。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56688359

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档