有没有一种方法可以获取链接到Go中的CGO代码的调试符号?

huangapple go评论120阅读模式
英文:

Is there a way to get debugging symbols for CGO code linked into Go?

问题

我有一些Cgo代码,我将其链接到我的Go二进制文件中。我已经成功运行Cgo并构建了我的代码和包装器。最近进行了一些更改后,我开始在链接的C++代码中遇到双重释放的问题。我尝试在lldb下运行我的二进制文件,它确实捕获了malloc错误,但符号并不是特别有用。

在普通的C或C++中,我使用-g3选项来获取包含变量名和源代码的丰富调试符号。这使得使用lldb更加高效。然而,我在我的Go二进制文件中无法获取这些符号。我注意到在回溯中,我的函数显示为main'foo,其中foo是我的函数名。然而,没有其他的调试信息,我只能得到一串汇编代码和内存指针/寄存器的跟踪信息。

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

英文:

I have some Cgo code that I'm linking into my Go binary. I've got Cgo running and building my code and wrapper. After some recent changes, I started getting a double-free in my C++ that I'm linking in. I've tried running my binary under lldb and it does trap the malloc panic, but the symbols are not especially useful.

In vanilla C or C++ I've used -g3 to get rich debugging symbols that includes variable names and source. This makes using lldb much more productive. However, I'm having some issues getting these symbols to show up in my go binary. I've noticed that in the backtrace my function appears as main'foo, where foo is the name of my function. There is no other debug info present though, all I get is a trace of assembly and memory pointers/registers.

I've tried invoking go build with CGO_CFLAGS="-g3" CGO_CXXFLAGS="-g3" but the binary still doesn't have the symbols. I've also tried adding -g3 to the CFLAGS/CXXFLAGS in my .go file where I set other flags (before import "C") but this doesn't seem to work either. I can't think of any other way to get this debugging info added into my binary - is there some Go-specific flag or build sequence that enables this?

答案1

得分: 0

我不知道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文件是否仍然在上述命令中看到的位置。可能是构建过程的某个部分将它们移动了,调试器无法再找到它们了。

英文:

I don't know how the process of go & C++ linking works. But a brief description of how debug information is handled on OS X might help you figure out where the debug information is being lost.

On OS X as on most systems, the debug information for an individual source file compile goes into the .o file made from it. You can verify that your .o file got debug information in a variety of ways, here's one:

 lldb -o &quot;image dump sections&quot; 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

If you don't see anything here, then the compiler isn't emitting debug information...

The next step is specific to Darwin, instead of putting the debug information into the output of the link stage, the debug info is left in the .o files, and a "debug map" is inserted into the output image. That's how the debugger finds its way back to the .o files. You can see that by doing:

$ nm -ap &lt;YourBinary&gt; | grep OSO

you should see a list of all your .o files here. If you don't then at some point in the build process your binary is getting stripped (using at least strip -S) You have to find out when that is happening and not do that. Also check that the .o files are still where the entries you see from the command above say they are. It may be some part of the build process is moving them around, and the debugger can't find them anymore.

huangapple
  • 本文由 发表于 2017年5月19日 04:18:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/44057079.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定