一些GDB命令–调试核心、反汇编和加载共享库

举报
Tiamo_T 发表于 2022/08/24 16:55:10 2022/08/24
【摘要】 本文解释了如何使用 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

有时共享库中甚至没有任何符号,在这种情况下,上述方法会很有帮助。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。