LLDB没有显示源代码

Leo*_*Leo 19 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
Run Code Online (Sandbox Code Playgroud)

我正在编译-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
Run Code Online (Sandbox Code Playgroud)

之前-O2是因为那是我正在使用的默认值,但我相信后者-O0会覆盖它,对吧?

我试过的

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

  2. 经过一些搜索,我试着运行dsymutil main.owarning: 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. 我在可执行文件和目标文件上运行dwarfdump(我在这里阅读).它看起来像我调试符号未经训练的眼睛出现在目标文件,而不是在可执行文件本身(除非dwarfdump只适用于目标文件,这是可能的).所以也许链接阶段是问题.或者DWARF可能存在问题.

  6. 我现在通过在终端中逐个发布构建命令,在"hello world"程序中工作.因此我猜测这可能是我的构建系统(Tup)的问题,可能运行具有不同工作目录的命令,因此路径被破坏或者某些东西.

Jas*_*nda 20

将-g命令行选项添加到clang时,DWARF调试信息将放入.o文件中.当您将目标文件(.o,ranlib archives又称静态库,即.a文件)链接到可执行文件/ dylib/framework/bundle时,"调试注释"将放入可执行文件中,以说明(1).o具有调试信息的etc文件的位置,以及(2)可执行二进制文件中函数/变量的最终地址.优化参数(-O0,-O2等)不具有对调试信息生成的影响-尽管调试与优化编译代码比调试在编译后的代码更加困难-O0.

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

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

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

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


小智 5

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