【发布时间】:2016-08-26 09:48:05
【问题描述】:
我正在尝试调试我正在编写的 C++ 程序,但是当我在 LLDB 中运行它并停止程序时,它只向我显示汇编程序,而不是原始源代码。 例如崩溃后我正在尝试调试:
Process 86122 stopped
* thread #13: tid = 0x142181, 0x0000000100006ec1 debug_build`game::update() + 10961, stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x0000000100006ec1 debug_build`game::update() + 10961
debug_build`game::update:
-> 0x100006ec1 <+10961>: movq (%rdx), %rdx
0x100006ec4 <+10964>: movq %rax, -0xb28(%rbp)
0x100006ecb <+10971>: movq -0x1130(%rbp), %rax
0x100006ed2 <+10978>: movq 0x8(%rax), %rsi
我正在使用-O0 -g 进行编译。通过 Xcode(我在 OSX 上)或从命令行运行调试器时,我看到了同样的情况。
我还需要做什么才能让源代码显示在 LLDB 中?
补充说明
这是一个典型的构建命令示例:
clang++ -std=c++1y -stdlib=libc++ -fexceptions -I/usr/local/include -c -O2 -Wall -ferror-limit=5 -g -O0 -ftrapv lib/format.cpp -o format.o
之前的-O2 在那里,因为这是我使用的默认值,但我相信后来的-O0 会覆盖它,对吧?
我的尝试
我用一个简单的“hello world”程序使用相同的构建设置重新创建了这个问题。
经过一番搜索,我尝试运行
dsymutil main.o,上面写着warning: no debug symbols in executable (-arch x86_64),所以也许我的构建命令没有生成调试符号?我也尝试将
-gsplit-dwarf添加到构建命令中,但没有任何效果。-
这是我的“hello world”版本的链接命令:
clang++ main.o -L/usr/local/lib -g -o hello
我在可执行文件和目标文件上运行了
dwarfdump(I read about it here)。在我未经训练的眼睛看来,调试符号 出现在目标文件中,但不在可执行文件本身中(除非dwarfdump仅适用于目标文件,这是可能的)。所以也许链接阶段是问题所在。或者也许 DWARF 有问题。我现在可以在“hello world”程序中使用它,方法是在终端中逐一发出构建命令。因此,我猜测这可能是我的构建系统 (Tup) 的问题,可能是使用不同的工作目录运行命令,因此路径会被破坏或其他原因。
【问题讨论】:
-
Xcode 有一个选项来'strip the executable',我想这会删除调试符号。检查是否设置了此选项。
-
我是从命令行构建的,而不是在 Xcode 中。有什么方法可能还会发生这种情况吗?也许在链接期间剥离可执行文件?我也会在上面添加我的链接命令...
-
imgur.com/a/idI6C 编辑:刚刚看到您正在使用命令行.. nvm.. 但我将把它留在这里以防万一您决定使用 Xcode。
-
谢谢!有什么方法可以查看与 Xcode 相同的 CLI 功能吗?我会戳一下,看看我是否可以这样做,可能会提供更多线索。
-
根据我上面的实验/编辑,这绝对是 Tup 构建工具。我使用了
dwarfdump以及各种基于 Tup 和非 Tup 的构建命令,它似乎正在破坏 DWARF 输出中的路径。 Tup 使用虚拟 FUSE 文件系统来确定构建命令的输出,所以可能就是这样。我会进一步更新这个问题,并在找到答案时提供答案。如果有人看到这个并知道 Tup 的解决方案,请告诉我,但我知道它是一个鲜为人知的工具。