使用 LLDB 调试具有特定调试符号的核心文件
Debug core file with specific debug symbols using LLDB
我有一个在发布和调试模式下构建的程序。我的程序发布的二进制文件在用户机器上崩溃了(为了简单起见,让 sysroots 相同),所以现在我从这个用户那里得到了一个核心文件。我想在我的 macOS 上使用 LLDB 调试这个核心文件。
假设我的机器上有这些文件:
a.out
a.out.dSYM
user_core
program.c
现在我正在尝试使用 LLDB 打开 user_core
,但没有可用的调试信息或源代码:
$ lldb
(lldb) target create --core user_core
Core file '~/user_core' (x86_64) was loaded.
(lldb) f
frame #0: 0x00000001023b4f77 a.out`main + 39
a.out`main:
-> 0x1023b4f77 <+39>: xorl %ecx, %ecx
0x1023b4f79 <+41>: movl %eax, -0xc(%rbp)
(lldb) image lookup -v --address 0x00000001023b4f77
Address: a.out[0x0000000100003f77] (a.out.__TEXT.__text + 39)
Summary: a.out`main + 39
Module: file = "~/a.out", arch = "x86_64"
Symbol: id = {0x00000002}, range = [0x00000001023b4f50-0x00000001023b4f84), name="main"
(lldb) image list
[ 0] <...> 0x00000001023b1000 ~/a.out (0x00000001023b1000)
执行(lldb) target modules add ~/a.out
后,得到:
[ 0] <UUID #0> 0x00000001023b1000 ~/a.out (0x00000001023b1000)
...
[ 44] <UUID #44> a.out[0x0000000100000000] ~/a.out
~/a.out.dSYM/Contents/Resources/DWARF/a.out
据我了解,a.out
已经加载了两次,但是LLDB仍然忽略了调试符号。
我也尝试过这些技巧,但没有效果:
- 使用
(lldb) target create a.out --symfile a.out.dSYM --core user_core
打开核心文件
- 在打开核心文件之前执行
(lldb) settings set target.debug-file-search-paths .
- 在打开核心文件之前执行
(lldb) setting set target.exec-search-paths .
- 执行
(lldb) target symbols add ~/a.out.dSYM
所以问题是如何使用 LLDB 使用指定的调试符号正确调试发布二进制文件的核心转储?
在进行核心文件调试时,您必须将二进制映像和核心文件都提供给lldb。但是除非 dSYM 位于与 a.out 不同的目录中(并且那个不同的位置是 Spotlight 没有索引的地方),否则您不需要传递符号文件。因此,您尝试过的事情列表中的第一个命令虽然有点多余,但应该有效。
您确定您的 a.out.dSYM 实际上与您的 a.out 二进制文件匹配吗?生成 dSYM 时,生成它的二进制文件的 UUID 将被复制到 dSYM 中,如果 lldb 与相关二进制文件的 UUID 匹配,则 lldb 将仅使用来自 dSYM 的调试信息。
您可以通过 运行 命令找到二进制文件或 dSYM 的 uuid:
$ dwarfdump -uuid
无法强制 lldb 对可执行文件使用错误的 dSYM。做任何有用的事情的可能性如此之低,以至于没有覆盖。
我有一个在发布和调试模式下构建的程序。我的程序发布的二进制文件在用户机器上崩溃了(为了简单起见,让 sysroots 相同),所以现在我从这个用户那里得到了一个核心文件。我想在我的 macOS 上使用 LLDB 调试这个核心文件。
假设我的机器上有这些文件:
a.out
a.out.dSYM
user_core
program.c
现在我正在尝试使用 LLDB 打开 user_core
,但没有可用的调试信息或源代码:
$ lldb
(lldb) target create --core user_core
Core file '~/user_core' (x86_64) was loaded.
(lldb) f
frame #0: 0x00000001023b4f77 a.out`main + 39
a.out`main:
-> 0x1023b4f77 <+39>: xorl %ecx, %ecx
0x1023b4f79 <+41>: movl %eax, -0xc(%rbp)
(lldb) image lookup -v --address 0x00000001023b4f77
Address: a.out[0x0000000100003f77] (a.out.__TEXT.__text + 39)
Summary: a.out`main + 39
Module: file = "~/a.out", arch = "x86_64"
Symbol: id = {0x00000002}, range = [0x00000001023b4f50-0x00000001023b4f84), name="main"
(lldb) image list
[ 0] <...> 0x00000001023b1000 ~/a.out (0x00000001023b1000)
执行(lldb) target modules add ~/a.out
后,得到:
[ 0] <UUID #0> 0x00000001023b1000 ~/a.out (0x00000001023b1000)
...
[ 44] <UUID #44> a.out[0x0000000100000000] ~/a.out
~/a.out.dSYM/Contents/Resources/DWARF/a.out
据我了解,a.out
已经加载了两次,但是LLDB仍然忽略了调试符号。
我也尝试过这些技巧,但没有效果:
- 使用
(lldb) target create a.out --symfile a.out.dSYM --core user_core
打开核心文件
- 在打开核心文件之前执行
(lldb) settings set target.debug-file-search-paths .
- 在打开核心文件之前执行
(lldb) setting set target.exec-search-paths .
- 执行
(lldb) target symbols add ~/a.out.dSYM
所以问题是如何使用 LLDB 使用指定的调试符号正确调试发布二进制文件的核心转储?
在进行核心文件调试时,您必须将二进制映像和核心文件都提供给lldb。但是除非 dSYM 位于与 a.out 不同的目录中(并且那个不同的位置是 Spotlight 没有索引的地方),否则您不需要传递符号文件。因此,您尝试过的事情列表中的第一个命令虽然有点多余,但应该有效。
您确定您的 a.out.dSYM 实际上与您的 a.out 二进制文件匹配吗?生成 dSYM 时,生成它的二进制文件的 UUID 将被复制到 dSYM 中,如果 lldb 与相关二进制文件的 UUID 匹配,则 lldb 将仅使用来自 dSYM 的调试信息。
您可以通过 运行 命令找到二进制文件或 dSYM 的 uuid:
$ dwarfdump -uuid
无法强制 lldb 对可执行文件使用错误的 dSYM。做任何有用的事情的可能性如此之低,以至于没有覆盖。