c - 当没有加载调试符号时,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

GDB 不会"解释"main

如果你的问题是"GDB如何知道main在哪里",答案是:"因为它的地址在符号表中"(见nm /root/ctest/printf的输出)。在UNIX(与Windows不同)上,不需要调试符号即可在可执行文件(或共享库)中包含函数和全局变量名称 - 默认情况下保留它们(以使调试更容易)。如果你想隐藏你的main,你可以运行strip printf从可执行文件中删除它(和所有其他符号)。

对于你的第二个问题,main没有被破坏,因为它有extern "C"联系。它必须具有该链接,以便可以从程序集调用它(它由 C 运行时启动调用,通常crt1.o )。

main不是

调试符号,因此不会剥离。 它具有外部链接,因此除非显式条带或链接命令将其删除,否则将保留它。 它不会被破坏,因为在大多数平台上,C ABI 中没有名称重整(除了可能附加下划线或类似内容)。

链接器和其他工具能够确定哪些符号是调试符号,哪些是外部或私有等,因为它们在符号表中的标记不同。 例如,在Mac OS X上,我们可能会看到这样的内容:

                 U _constantFromAnotherModule
0000000000000018 T _externFunction
0000000000000410 s _privateInt
0000000000000000 t _staticFunction

中间列中符号名称之前的不同字母表示不同类型的链接,并且工具对它们的处理方式不同。

即使符号破坏,工具通常也知道如何撤消重整,因此调试器应该能够在符号表中找到函数名称,即使它已被破坏,只要它是由与调试器兼容的工具构建的。 除此之外,main( ) C++具有C链接,并遵循平台的C ABI,因此通常不会被破坏。

最新更新