17

当我尝试调试可执行文件时:

(gdb) break +1
No symbol table is loaded.  Use the "file" command.

这到底是什么意思?

符号表是否附加到可执行文件中?

4

4 回答 4

27

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
$
于 2010-04-05T06:11:27.453 回答
8

这是因为您没有在打开调试的情况下编译。试试 gcc -g file.c

于 2010-04-05T05:39:54.703 回答
4

符号表包含调试信息,告诉调试器哪些内存位置对应于原始源代码文件中的哪些符号(如函数名和变量名)。符号表通常存储在可执行文件中,是的。

gdb 告诉您它找不到该表。如果你用 gcc 编译,除非你使用了 -g 标志,否则它不会在文件中包含符号表。最简单的方法可能是使用 -g 重新编译文件。然后 gdb 应该会自动找到符号表信息。

将 -g 标志添加到 gcc 的命令行参数或用于编译程序的 Makefile。(很多时候,Makefile 中会有一个名为 CFLAGS 或类似的变量)。

如果您尝试调试任意第三方程序,很多时候信息将被“剥离”出来。这样做是为了使逆向工程更难,并使可执行文件的大小更小。除非您可以访问源代码并且可以自己编译程序,否则您将很难在其上使用 gdb。

于 2010-04-05T05:44:58.753 回答
3

找到应用程序的入口点。

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

解决方案是在入口点地址加一开始调试。

于 2011-04-25T05:47:57.840 回答