什么是符号表以及它如何集成到可执行文件中?

发布于 2024-08-28 09:19:19 字数 155 浏览 10 评论 0原文

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

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

这到底是什么意思?

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

When I tried to debug an executable:

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

What does that mean exactly?

Is the symbol table appended to the executable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

紫南 2024-09-04 09:19:19

gdb 使用两组符号。

-g 集是调试符号,这使事情变得更加容易,因为它们允许您在调试时查看代码并查看变量。

编译时默认包含另一组符号。这些是链接符号,存在于 ELF(可执行可链接格式)符号表中。它包含的信息比调试符号少得多,但包含最重要的内容,例如可执行文件(或库或目标文件)中内容的地址。如果没有这些信息,gdb 甚至不知道 main 在哪里,因此 (gdb) break main 将失败。

如果您没有调试符号 ( -g ),那么您仍然可以(gdb) break main,但您的 gdb 对源文件中的代码行没有任何概念。当您尝试单步执行代码时,一次只会前进 1 个机器指令,而不是一次前进一行。

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
$

There are two sets of symbols that gdb uses.

The -g set are debugging symbols, which make things a lot easier as they allow you to see your code and look at variables while debugging.

Another set of symbols is included by default when you compile. These are the linking symbols and live in the ELF (executable linkable format) symbol table. This contains a lot less info than the debug symbols, but contain the most important stuff, such as the addresses of the things in your executable (or library or object file). Without this information gdb won't even know where main is, so (gdb) break main would fail.

If you don't have the debugging symbols ( -g ) then you will still be able to (gdb) break main but you gdb will not have any concept of the lines of code in your source file. When you try to step through the code you will only advance 1 machine instruction at a time, rather than a line at a time.

The strip command is often used to strip off symbols from an executable (or other object file).
This is often used if you don't want someone to be able to see the symbols or if you want to save space in the file. Symbol tables can get big. Strip removes both the debug symbols and the linker symbols, but it has several command line switches which can limit what it removes.

If you run the file command on your program one of the things it will tell you is weather or not the executable is has been stripped.

$ 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
$
海之角 2024-09-04 09:19:19

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

It's because you didn't compile with debugging turned on. Try gcc -g file.c

过期情话 2024-09-04 09:19:19

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

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

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

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

The symbol table contains debugging information that tells a debugger what memory locations correspond to which symbols (like function names and variable names) in the original source code file. The symbol table is usually stored inside the executable, yes.

gdb is telling you that it can't find that table. If you compiled with gcc, unless you used the -g flag, it will not include the symbol table in the file. The easiest method is probably to recompile your file with -g. gdb should then automatically find the symbol table information.

Either add the -g flag to the command line arguments of gcc or to the Makefile that you used to compile the program. (A lot of times, there will be a variable called CFLAGS or similar inside the Makefile).

If you are trying to debug an arbitrary third-party program, a lot of times the information will have been "stripped" out of it. This is done to make reverse engineering harder and to make the size of the executable file smaller. Unless you have access to the source code and can compile the program yourself, you will have a very hard time using gdb on it.

黯淡〆 2024-09-04 09:19:19

找到应用程序的入口点。

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

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

Find the entry point of the application.

objdump -f main

    main:     file format elf32-i386
    architecture: i386, flags 0x00000112:
    EXEC_P, HAS_SYMS, D_PAGED
    start address 0x08048054

Put a breakpoint there using the gnu debugger

gdb

    exec-file main
    break *0x8048054
    set disassemble-next-line on
    run

Then step through the code

gdb

    stepi

Special Notes

If you are using the latest version of Ubuntu you would not be affected by this, but you may run into this bug if you are running Ubuntu 10.04 or older.

https://bugs.launchpad.net/ubuntu/+source/gdb/+bug/151518G

The solution would be to start debugging at the entry point address plus one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文