一些GDB命令–调试核心、反汇编和加载共享库
GDB 是程序员调试代码的必备工具。
本文解释了如何使用 gdb 调试带有核心文件的程序,如何显示程序的汇编语言指令,以及如何加载共享库程序进行调试。
使用核心文件调试程序
核心文件或核心转储是记录正在运行的进程的内存映像及其状态的文件。它用于在调试器外部运行时崩溃的程序的事后调试。
$ gdb executable_name core_file_name
(gdb)
上述命令将加载可执行文件的核心文件并提示 gdb shell。
您可以使用gdb backtrace或其他命令来检查实际发生的发生的情况。请注意,如果可执行文件在 gdb 下运行,core_file 将被忽略。
打印组装说明
您可以使用 disassemble 命令打印函数的汇编指令。您也可以指定2个地址范围,它们之间的指令将被反汇编并打印反汇编并打印在gdb控制台中。
(gdb) disassemble main
Dump of assembler code for function main:
0x00000000004004ac : push %rbp
0x00000000004004ad : mov %rsp,%rbp
0x00000000004004b0 : mov $0x0,%eax
0x00000000004004b5 : pop %rbp
0x00000000004004b6 : retq
End of assembler dump.
加载共享库符号
很多时候,程序员会在他们的代码中使用共享库。有时,我们可能想查看共享库本身以了解发生了什么。在这里,我将展示一个使用 GLib 库的示例以及如何获取它的调试信息。
默认情况下,所有发行版都会在某种程度上剥离库。完整的调试信息将存储在一个单独的包中,他们将其命名为“package-1.0-dbg”,并且只有在需要时用户才能安装。
当您安装“package-1.0-dbg”时,默认情况下 gdb 会加载所有调试信息,但为了理解这里的概念,我们将看到如何手动加载符号文件。
#include <stdio.h>
#include <glib.h>
struct a {
int a;
int b;
};
void *print( struct a *obj,int as) {
printf("%d:%d\n",obj->a,obj->b);
}
int main() {
struct a *obj;
obj = (struct a*)malloc(sizeof(struct a));
obj->a=3;
obj->b=4;
GList *list=NULL;
list = g_list_append(list,obj);
g_list_foreach(list,(GFunc)print,NULL);
}
$ cc -g -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ -lglib-2.0 glib_test.c
注意:您需要安装 libglib2.0-0 才能试用此示例。
现在我们将开始调试。
(gdb) b 1
Breakpoint 1 at 0x4007db: file a.c, line 1.
(gdb) run
...
(gdb) info sharedlibrary
From To Syms Read Shared Object Library
0x00007ffff7dddaf0 0x00007ffff7df5c83 Yes (*) /lib64/ld-linux-x86-64.so.2
0x00007ffff7b016c0 0x00007ffff7b6e5cc Yes (*) /lib/x86_64-linux-gnu/libglib-2.0.so.0
0x00007ffff7779b80 0x00007ffff7890bcc Yes (*) /lib/x86_64-linux-gnu/libc.so.6
0x00007ffff751f9a0 0x00007ffff7546158 Yes (*) /lib/x86_64-linux-gnu/libpcre.so.3
0x00007ffff7307690 0x00007ffff7312c78 Yes (*) /lib/x86_64-linux-gnu/libpthread.so.0
0x00007ffff70fc190 0x00007ffff70ff4f8 Yes (*) /lib/x86_64-linux-gnu/librt.so.1
(*): Shared library is missing debugging information.
从以上信息中,请注意库 libglib-2.0.so.0 有符号,但缺少调试信息,如 file_name、line_no 等。
从各自的发行版下载软件包的调试信息(Debian – Wheezy 中的 libglib2.0-0-dbg)。
(gdb) add-symbol-file /home/lakshmanan/libglib-2.0.so.0.3200.4 0x00007ffff7b016c0
add symbol table from file "/home/lakshmanan/libglib-2.0.so.0.3200.4" at
.text_addr = 0x7ffff7b016c0
(y or n) y
Reading symbols from /home/lakshmanan/libglib-2.0.so.0.3200.4...done.
add-symbol-file 命令中给出的地址是“info sharedlibrary”命令打印的“From”地址。现在调试信息已加载。
(gdb) n
g_list_foreach (list=0x0, func=0x4007cc , user_data=0x0) at /tmp/buildd/glib2.0-2.33.12+really2.32.4/./glib/glist.c:897
有时共享库中甚至没有任何符号,在这种情况下,上述方法会很有帮助。
- 点赞
- 收藏
- 关注作者
评论(0)