【发布时间】:2010-04-05 05:31:17
【问题描述】:
当我尝试调试可执行文件时:
(gdb) break +1
No symbol table is loaded. Use the "file" command.
这到底是什么意思?
符号表是否附加到可执行文件中?
【问题讨论】:
标签: gdb symbol-tables executable-format
当我尝试调试可执行文件时:
(gdb) break +1
No symbol table is loaded. Use the "file" command.
这到底是什么意思?
符号表是否附加到可执行文件中?
【问题讨论】:
标签: gdb symbol-tables executable-format
gdb 使用了两组符号。
-g 集是调试符号,它使事情变得更容易,因为它们允许您在调试时查看代码并查看变量。
编译时默认包含另一组符号。这些是链接符号,位于 ELF(可执行链接格式)符号表中。它包含的信息比调试符号少得多,但包含最重要的东西,例如可执行文件(或库或目标文件)中的东西的地址。如果没有这些信息,gdb 甚至都不知道 main 在哪里,所以 (gdb) break main 会失败。
如果您没有调试符号 (-g),那么您仍然可以使用(gdb) break main,但您的 gdb 将不会对源文件中的代码行有任何概念。当您尝试单步执行代码时,您一次只能推进 1 条机器指令,而不是一次一行。
strip 命令通常用于strip 关闭可执行文件(或其他目标文件)中的符号。
如果您不想让别人看到这些符号,或者您想节省文件空间,这通常会用到。符号表可以变大。 Strip 会删除调试符号和链接器符号,但它有几个命令行开关可以限制它删除的内容。
如果您在程序上运行file 命令,它会告诉您的一件事是天气或可执行文件是否已被剥离。
$ gcc my_prog.c -o my_prog
$ file my_prog
my_prog: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
$ strip my_prog
my_prog: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped
$
【讨论】:
.dynsym,对吗?)被 strip 删除?根据this 他们不是。
strip 具有控制哪些符号被删除和不被删除的选项。默认行为通常不会破坏事情。
-g 标志对许多编译器来说意味着“请调试符号”,但他们可以在没有它的情况下添加符号或不使用它生成它们。这些符号具有“代码地址=>(函数:行号)”和“在此代码地址处,X 的最新值在此寄存器中”之类的信息。
这是因为你没有打开调试编译。试试 gcc -g file.c
【讨论】:
符号表包含调试信息,告诉调试器哪些内存位置对应于原始源代码文件中的哪些符号(如函数名和变量名)。符号表通常存储在可执行文件中,是的。
gdb 告诉你它找不到那个表。如果你用 gcc 编译,除非你使用了 -g 标志,否则它不会在文件中包含符号表。最简单的方法可能是使用 -g 重新编译文件。然后 gdb 应该会自动找到符号表信息。
将 -g 标志添加到 gcc 的命令行参数或用于编译程序的 Makefile。 (很多时候,Makefile里面会有一个叫做CFLAGS或者类似的变量)。
如果您尝试调试任意第三方程序,很多时候信息会被“剥离”出来。这样做是为了使逆向工程更难,并使可执行文件的大小更小。除非您可以访问源代码并且可以自己编译程序,否则您将很难在其上使用 gdb。
【讨论】:
No symbol table is loaded. Use the "file" command. 响应,它似乎不可能在没有符号表的情况下调试程序..或者也许我错过了什么?
-g”。你也不能指定'-s'(strip),也不能让程序服从'strip'。
找到应用程序的入口点。
objdump -f main
main: file format elf32-i386
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x08048054
使用 gnu 调试器在此处设置断点
gdb
exec-file main
break *0x8048054
set disassemble-next-line on
run
然后单步执行代码
gdb
stepi
特别说明
如果您使用的是最新版本的 Ubuntu,则不会受到此影响,但如果您运行的是 Ubuntu 10.04 或更早版本,则可能会遇到此错误。
https://bugs.launchpad.net/ubuntu/+source/gdb/+bug/151518G
解决方案是从入口点地址加一开始调试。
【讨论】: