Debugging 有没有办法将CGO代码的调试符号链接到Go中?

Debugging 有没有办法将CGO代码的调试符号链接到Go中?,debugging,go,lldb,Debugging,Go,Lldb,我有一些Cgo代码,我正在链接到我的Go二进制文件中。我已经让Cgo运行并构建了我的代码和包装器。在最近的一些变化之后,我开始在我的C++中获得一个双链,我正在链接。我曾尝试在lldb下运行我的二进制文件,它确实捕获了malloc恐慌,但符号并不是特别有用 在香草C或C++中,我使用了>G3,获得了包含变量名称和源代码的丰富的调试符号。这使得使用lldb更加高效。然而,让这些符号出现在我的go二进制文件中有一些问题。我注意到在回溯中,我的函数显示为main'foo,其中foo是我函数的名称。虽然

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

在香草C或C++中,我使用了>G3,获得了包含变量名称和源代码的丰富的调试符号。这使得使用lldb更加高效。然而,让这些符号出现在我的go二进制文件中有一些问题。我注意到在回溯中,我的函数显示为
main'foo
,其中foo是我函数的名称。虽然没有其他调试信息,但我得到的只是汇编和内存指针/寄存器的跟踪


我已经尝试使用
CGO\u CFLAGS=“-g3”CGO\u cxflags=“-g3”
调用
go build
,但二进制文件仍然没有符号。我还尝试将
-g3
添加到.go文件中的CFLAGS/cxflags中,我在其中设置了其他标志(在
导入“C”
之前),但这似乎也不起作用。我想不出有什么其他的方法可以把这个调试信息添加到我的二进制文件中——有一些GO特定的标志或构建序列可以实现这个吗?< /P> < P>我不知道Go+C++链接的工作原理。但是,简要描述一下在OSX上如何处理调试信息可能会帮助您找出调试信息丢失的地方

在OSX上,与在大多数系统上一样,单个源文件编译的调试信息进入由其生成的.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
$nm-ap | grep OSO

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

< P>我不知道Go+C++链接的工作流程。但是,简要描述一下在OSX上如何处理调试信息可能会帮助您找出调试信息丢失的地方

在OSX上,与在大多数系统上一样,单个源文件编译的调试信息进入由其生成的.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
$nm-ap | grep OSO

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

您是否碰巧在darwin上?是的,我是。因此,从阅读这篇文章来看,Go当时似乎已经坏了,团队不打算修复它。这太遗憾了:/如果您使用的是xcode而不是gcc,那么这个问题听起来应该可以解决。如果你使用C++,也许它也与Sigg有关系。对于这个问题,邮件列表可能是一个更好的资源。在我的例子中,我使用的是llvm/clang,而不是swig,只是香草C++你碰巧在达尔文吗?是的,我是。因此,从阅读这篇文章来看,Go当时似乎已经坏了,团队不打算修复它。这太遗憾了:/如果您使用的是xcode而不是gcc,那么这个问题听起来应该可以解决。如果你使用C++,也许它也与Sigg有关系。邮件列表可能是这个问题的一个更好的资源。在我的例子中,我使用LLVM/CLAN,没有SWIG,只是香草C++。