当没有加载调试符号时,gdb 如何解释“main”?
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/ctest/printf...(no debugging symbols found)...done.
(gdb) disas main
Dump of assembler code for function main:
0x0000000000400498 <main+0>: push %rbp
0x0000000000400499 <main+1>: mov %rsp,%rbp
0x000000000040049c <main+4>: sub $0x10,%rsp
当没有加载调试符号时,gdb 如何解释 main
?
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/ctest/printf...(no debugging symbols found)...done.
(gdb) disas main
Dump of assembler code for function main:
0x0000000000400498 <main+0>: push %rbp
0x0000000000400499 <main+1>: mov %rsp,%rbp
0x000000000040049c <main+4>: sub $0x10,%rsp
How does gdb interpret main
when no debug symbols loaded?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
GDB 不会“解释”
main
。如果您的问题是“GDB 如何知道 main 在哪里”,答案是:“因为它的地址在符号表中”(请参阅 nm /root/ctest/printf 的输出)。在 UNIX 上(与 Windows 不同),不需要调试符号来在可执行文件(或共享库)中包含函数和全局变量名称 - 默认情况下保留它们(以使调试更容易)。如果您想隐藏
main
,您可以运行strip printf
将其(以及所有其他符号)从可执行文件中删除。对于第二个问题,
main
没有被破坏,因为它具有extern "C"
链接。它必须具有该链接,以便可以从程序集调用它(它由 C 运行时启动调用,通常是crt1.o
)。GDB doesn't "interpret"
main
.If your question is "how does GDB know where main is", the answer is: "because its address is in the symbol table" (see output from
nm /root/ctest/printf
). On UNIX (unlike Windows) one doesn't need debug symbols to have function and global variable names in the executable (or shared library) -- they are kept by default (to make debugging easier). If you wanted to hide yourmain
, you could runstrip printf
to remove it (and all other symbols) from the executable.For your second question,
main
isn't mangled because it hasextern "C"
linkage. It must have that linkage so it can be called from assembly (it is called by the C runtime startup, usuallycrt1.o
).main
不是调试符号,因此不会被删除。它具有外部链接,因此除非显式删除或链接命令将其删除,否则它会被保留。它没有被破坏,因为在大多数平台上,C ABI 中没有名称破坏(除了附加下划线或类似内容)。链接器和其他工具能够确定哪些符号是调试符号,哪些符号是外部符号或私有符号等,因为它们在符号表中的标记不同。例如,在 Mac OS X 上,我们可能会看到这样的内容:
中间列中符号名称之前的不同字母表示不同类型的链接,并且工具对它们的处理方式不同。
即使符号被损坏,工具通常知道如何撤消损坏,因此调试器应该能够在符号表中找到函数名称,即使它已被损坏,只要它是由与调试器兼容的工具构建。除此之外,C++ 中的
main( )
具有 C 链接,并遵循平台的 C ABI,因此它通常不会被破坏。main
isn't a debug symbol, so it isn't stripped. It has external linkage, so it is preserved unless an explicit strip or link command removes it. It isn't mangled because on most platforms, there is no name mangling in the C ABI (except maybe for appending an underscore or similar).The linker and other tools are able to determine what symbols are debug symbols and which are extern, or private, etc, because they are marked differently in the symbol table. For example, on Mac OS X, we might see something like this:
The different letters in the middle column, before the symbol names, indicate different types of linkage, and they are treated differently by the tools.
Even if the symbols are mangled, tools often know how to undo the mangling, so a debugger should be able to find a function name in a symbol table even if it has been mangled, so long as it was built by tools compatible with the debugger. Beyond that,
main( )
in C++ has C linkage, and follows the platform's C ABI, so it is typically not mangled.