debugging - 有没有办法为链接到 Go 的 CGO 代码获取调试符号?

标签 debugging go lldb

我有一些 Cgo 代码正在链接到我的 Go 二进制文件中。我已经让 Cgo 运行并构建我的代码和包装器。在最近的一些更改之后,我开始在我正在链接的 C++ 中获得 double-free。我尝试在 lldb 下运行我的二进制文件,它确实捕获了 malloc panic ,但这些符号并不是特别有用。

在 vanilla C 或 C++ 中,我使用 -g3 来获得丰富的调试符号,其中包括变量名称和源代码。这使得使用 lldb 的效率更高。但是,我在将这些符号显示在我的 go 二进制文件中时遇到了一些问题。我注意到在回溯中我的函数显示为 main'foo,其中 foo 是我的函数的名称。虽然没有其他调试信息,但我得到的只是汇编和内存指针/寄存器的踪迹。

我已经尝试使用 CGO_CFLAGS="-g3"CGO_CXXFLAGS="-g3" 调用 go build 但二进制文件仍然没有符号。我还尝试将 -g3 添加到我的 .go 文件中的 CFLAGS/CXXFLAGS 中,我在其中设置了其他标志(在 import "C" 之前),但这似乎没有要么工作。我想不出任何其他方法可以将此调试信息添加到我的二进制文件中 - 是否有一些特定于 Go 的标志或构建序列可以启用此功能?

最佳答案

我不知道 go & C++ 链接的过程是如何工作的。但是,对调试信息在 OS X 上的处理方式的简要说明可能会帮助您找出调试信息丢失的位置。

与大多数系统一样,在 OS X 上,单个源文件编译的调试信息进入由它生成的 .o 文件。您可以通过多种方式验证您的 .o 文件是否获得了调试信息,这是一种方式:

 lldb -o "image dump sections" Target.o --batch | grep DWARF
  0x00000300 container        [0x0000000000061538-0x0000000000782c77)  rwx  0x00061cb8 0x0072173f 0x00000000 Target.o.__DWARF
  0x00000009 dwarf-str        [0x0000000000061538-0x00000000004eeabc)  rwx  0x00061cb8 0x0048d584 0x02000000 Target.o.__DWARF.__debug_str
  0x0000000a dwarf-loc        [0x00000000004eeabc-0x00000000004ef493)  rwx  0x004ef23c 0x000009d7 0x02000000 Target.o.__DWARF.__debug_loc
  0x0000000b dwarf-abbrev     [0x00000000004ef493-0x00000000004f09a7)  rwx  0x004efc13 0x00001514 0x02000000 Target.o.__DWARF.__debug_abbrev
  0x0000000c dwarf-info       [0x00000000004f09a7-0x00000000006ea7f1)  rwx  0x004f1127 0x001f9e4a 0x02000000 Target.o.__DWARF.__debug_info
  0x0000000d dwarf-ranges     [0x00000000006ea7f1-0x00000000006ec481)  rwx  0x006eaf71 0x00001c90 0x02000000 Target.o.__DWARF.__debug_ranges
  0x0000000e dwarf-macinfo    [0x00000000006ec481-0x00000000006ec482)  rwx  0x006ecc01 0x00000001 0x02000000 Target.o.__DWARF.__debug_macinfo
  0x0000000f apple-names      [0x00000000006ec482-0x000000000071134e)  rwx  0x006ecc02 0x00024ecc 0x02000000 Target.o.__DWARF.__apple_names
  0x00000010 apple-objc       [0x000000000071134e-0x0000000000711372)  rwx  0x00711ace 0x00000024 0x02000000 Target.o.__DWARF.__apple_objc
  0x00000011 apple-namespaces [0x0000000000711372-0x00000000007116d6)  rwx  0x00711af2 0x00000364 0x02000000 Target.o.__DWARF.__apple_namespac
  0x00000012 apple-types      [0x00000000007116d6-0x0000000000748797)  rwx  0x00711e56 0x000370c1 0x02000000 Target.o.__DWARF.__apple_types
  0x00000015 dwarf-line       [0x000000000075d348-0x0000000000782c77)  rwx  0x0075dac8 0x0002592f 0x02000000 Target.o.__DWARF.__debug_line

如果你在这里没有看到任何东西,那么编译器没有发出调试信息......

下一步是 Darwin 特有的,不是将调试信息放入链接阶段的输出,而是将调试信息留在 .o 文件中,并在输出图像中插入“调试图”。这就是调试器找到返回 .o 文件的方式的方式。您可以通过执行以下操作看到这一点:

$ nm -ap <YourBinary> | grep OSO

您应该会在此处看到所有 .o 文件的列表。如果您不这样做,那么在构建过程中的某个时刻您的二进制文件将被剥离(至少使用 strip -S),您必须找出发生这种情况的时间而不是那样做。还要检查 .o 文件是否仍在您从上面的命令中看到的条目所在的位置。可能是构建过程的某些部分正在移动它们,调试器再也找不到它们了。

关于debugging - 有没有办法为链接到 Go 的 CGO 代码获取调试符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44057079/

相关文章:

c++ - Visual Studio - 如何在显示消息框后捕获调试(中断)

c++ - 分析崩溃

javascript - 如何找到导致 :hover action on DOM element? 的代码

json - 取消具有可变数量的相似字段的 JSON 对象

objective-c - 如何从 lldb 中的 objc 访问快速便利变量?

visual-studio-2010 - Trace.WriteLine 不产生任何输出

go - cassandra中复合键的二级索引

go - 基于拆分字符串和键值对生成动态嵌套映射

swift - 在 Ubuntu 18.04 中使用 LLDB 调试 Swift 5.1 时<无法解析类型>

c++ - 设置条件时 lldb 失败