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