≡菜单

很少的GDB命令–调试核心,反汇编,加载共享库

GDB是程序员调试代码的必备工具。

本文介绍了如何使用gdb调试带有核心文件的程序,如何显示程序的汇编语言指令以及如何加载共享库程序以进行调试。

使用核心文件调试程序

核心文件或核心转储是一个记录正在运行的进程及其状态的内存映像的文件。它用于在调试器外运行时崩溃的程序的事后调试。

$ gdb executable_name core_file_name

(gdb) 

上面的命令将为可执行文件加载核心文件,并提示一个gdb shell。

您可以使用 gdb回溯 或其他命令来检查实际发生的情况。请注意,如果可执行文件在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.

加载共享库符号

程序员常常会在代码中使用共享库。有时,我们可能想查看共享库本身以了解什么’s going 上 . Here I’图11显示了一个使用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) 信息共享库 
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等… are missing.

从各个发行版下载软件包的调试信息(Debian中的libglib2.0-0-dbg– Wheezy).

(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命令中给出的地址是“From” address printed 通过 “info sharedlibrary”命令。现在,调试信息已加载。

...
...
(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

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

如果您喜欢这篇文章,您可能还会喜欢..

  1. 50个Linux Sysadmin教程
  2. 50个最常用的Linux命令(包括示例)
  3. 排名前25位的最佳Linux性能监视和调试工具
  4. 妈妈,我找到了! – 15个实用的Linux Find命令示例
  5. Linux 101 Hacks第二版电子书 Linux 101黑客手册

Bash 101 Hacks书 Sed和Awk 101黑客手册 Nagios Core 3书 Vim 101黑客手册

{ 5 评论 … 加一 }

  • 黄昏科西嘉 2014年3月12日,上午12:42

    如果我知道了,就有可能得到汇编程序的源代码。就像数学中的逆函数一样。就像您从什么开始一样,获得了正确的代码。如果您知道已开发的语言,已使用的优化和产品。简而言之,您可以从攻击者那里得到代码。

  • 黄昏科西嘉 2014年3月12日,上午1:27

    意味着一切都是开源的!还有一件事,当您在商店中购买香水时,有时与其他香水类似,但是合法生产,但是当某人购买了完全不是原始文件的mp3时,则不合法分发该文件。是的,还有更多没有法律意义的事情。

  • 贾拉尔·哈吉霍拉玛利 2014年3月12日,晚上9:26

    你好

    非常感谢。

  • 普拉蒂克 2014年3月26日,上午3:10

    嗨Ramesh,
    我只是想知道是否有一种方法可以在gdb中列出程序的变量?

    问候
    普拉蒂克

  • 阿比舍克 2014年9月7日,上午10:55

    我发现本文很有用,但我需要有关如何调试coredump的详细信息?
    或者,请提供一些好的参考资料,以便我自己阅读。

    问候,
    阿比舍克

发表评论