当我尝试调试可执行文件时:
(gdb) break +1
No symbol table is loaded. Use the "file" command.
这到底是什么意思?
符号表是否附加到可执行文件中?
当我尝试调试可执行文件时:
(gdb) break +1
No symbol table is loaded. Use the "file" command.
这到底是什么意思?
符号表是否附加到可执行文件中?
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
$
这是因为您没有在打开调试的情况下编译。试试 gcc -g file.c
符号表包含调试信息,告诉调试器哪些内存位置对应于原始源代码文件中的哪些符号(如函数名和变量名)。符号表通常存储在可执行文件中,是的。
gdb 告诉您它找不到该表。如果你用 gcc 编译,除非你使用了 -g 标志,否则它不会在文件中包含符号表。最简单的方法可能是使用 -g 重新编译文件。然后 gdb 应该会自动找到符号表信息。
将 -g 标志添加到 gcc 的命令行参数或用于编译程序的 Makefile。(很多时候,Makefile 中会有一个名为 CFLAGS 或类似的变量)。
如果您尝试调试任意第三方程序,很多时候信息将被“剥离”出来。这样做是为了使逆向工程更难,并使可执行文件的大小更小。除非您可以访问源代码并且可以自己编译程序,否则您将很难在其上使用 gdb。
找到应用程序的入口点。
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
解决方案是在入口点地址加一开始调试。