LLDB未显示源代码

时间:2016-05-01 15:58:56

标签: c++ lldb clang++ tup

我正在尝试调试我正在编写的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会覆盖它,对吧?

我尝试了什么

  1. 我使用相同的构建设置通过一个简单的“hello world”程序重新创建了这个问题。

  2. 经过一番搜索后,我尝试运行dsymutil main.o warning: no debug symbols in executable (-arch x86_64),所以也许我的构建命令没有生成调试符号?

  3. 我也尝试在构建命令中添加-gsplit-dwarf但没有效果。

  4. 以下是我的'hello world'版本的链接命令:

    clang ++ main.o -L / usr / local / lib -g -o hello

  5. 我在可执行文件和目标文件上运行dwarfdumpI read about it here)。它看起来像我的未经训练的眼睛,如目标文件中存在的调试符号 ,但不存在于可执行文件本身中(除非dwarfdump仅适用于目标文件,这是可能的)。所以也许链接阶段是问题。或者DWARF可能存在问题。

  6. 我现在通过在终端中逐个发布构建命令,让它在'hello world'程序中工作。因此我猜测这可能是我的构建系统(Tup)的一个问题,可能使用不同的工作目录运行命令,因此路径会被破坏或者其他东西。

2 个答案:

答案 0 :(得分:19)

将-g命令行选项添加到clang时,DWARF调试信息将放在.o文件中。当您将目标文件(.o,ranlib归档,又名静态库,即.a文件)链接到可执行文件/ dylib / framework / bundle,&#34;调试说明&#34;在可执行文件中放入(1).o etc文件的位置和调试信息,以及(2)可执行二进制文件中函数/变量的最终地址。优化标志(-O0-O2等)对调试信息生成没有影响 - 尽管使用优化编译的调试代码比调试-O0生成的代码要困难得多。

如果您在该可执行二进制文件上运行调试器 - 无需任何其他修改 - 调试器将从.o等文件 中读取调试信息,只要它们是&#d;在构建可执行文件时,仍然在同一文件路径上的文件系统 。这使得迭代开发变得快速 - 没有工具需要读取,更新和输出(大)调试信息。你可以看到这些&#34;调试笔记&#34;在可执行文件中,通过运行nm -pa exename并查找OSO个条目(以及其他条目)。这些是stabs nlist条目,并且在您的可执行文件上运行strip(1)将删除它们。

如果要将所有调试信息(在.o文件中)收集到独立包中,则在可执行文件上运行dsymutil。这使用调试注释(假设:(1).o文件仍在其原始位置,(2)可执行文件尚未被剥离)以创建&#34; dSYM包&# 34 ;.如果二进制文件是 exename ,则dSYM包是 exename.dSYM 。当调试器在 exename 上运行时,它将在dSYM包的二进制文件旁边显示。如果在那里找不到,它将进行Spotlight搜索以查看dSYM是否位于计算机上的聚光灯索引位置。

您可以在dwarfdump文件或dSYM软件包上运行.o - 它们都包含调试信息。 dwarfdump无法在输出可执行文件中找到任何调试信息。

所以,正常的工作流程:用-g编译。链接可执行映像。如果是迭代开发,请运行调试器。如果运送/存档二进制文件,请创建dSYM,删除可执行文件。

答案 1 :(得分:3)

我通过使用(lldb) target symbols add a.out.dSYM命令添加调试符号的路径解决了这个问题,该路径存在于a.out.dSYM目录中。