GDB 常用命令

2019-02-10  本文已影响0人  wayyyy

官方文档

http://sourceware.org/gdb/current/onlinedocs/gdb/

确定文件是否可以gdb调试

gdb 直接调试查看

使用GDB调试

编译时使用-g编译选项
$ gcc -g program.c -o programname
在gdb中启动程序
$ gdb programname 
(gdb) run arg1 "arg2" ...
在gdb中重启程序
(gdb) kill
Kill the program being debugged? (y or n) y
(gdb) run
退出gdb
(gdb) quit
The program is running. Exit anyway? (y or n) 
调试已经运行的程序

假设已经获取到的进程PID=20829

$ gdb
(gdb) attach 20829

也可以直接使用gdb program pid,例如:

gdb hello 20829
当运行程序没有调试信息

为了节省磁盘空间,已经运行的程序通常没有调试信息。但如果又不能停止当前程序重新启动调试,那怎么办呢?
还有办法,那就是同样的代码,再编译出一个带调试信息的版本。然后使用和前面提到的方式操作。对于attach方式,在attach之前,使用file命令即可。

$ gdb
(gdb) file a.out
单步调试
until命令

查看变量

最常见的使用便是使用print(可简写为p)打印变量内容。

(gdb) p a

当然有时候,多个函数或者多个文件会有同一个变量名,这个时候可以在前面加上函数名或者文件名来区分。

(gdb) p 'main'::b
动态数组

int *array = (int *) malloc (len * sizeof (int));

(gdb) p *array@len
查看变量类型
(gdb) ptype el->fired
type = struct aeFiredEvent {
    int fd;
    int mask;
} *
自动显示变量

我们希望程序断住时,就显示某个变量的值,可以在断点被断住时使用display命令

(gdb) display e

执行shell命令

在gdb命令行界面可以执行外部的Shell命令

(gdb) !ls
a.out test.c

或者:

(gdb) shell ls
a.out test.c

查看当前代码运行位置
(gdb) where
#0  event_base_loop (base=0x602010, flags=0) at event.c:466
#1  0x00007ffff7bbb5c7 in event_base_dispatch (event_base=0x602010) at event.c:405
#2  0x0000000000400858 in main () at test.c:20

查看源代码
(gdb) l 

指定源码路径

在查看源码之前,首先要确保我们的程序能够关联到源码,一般来说,我们在自己的机器上加上-g参数编译完之后,使用gdb都能查看到源码,但是如果出现下面的情况呢?源码被移走。gdb调试就会提示找不到源码文件了,那么怎么办呢?可以使用dir命名指定源码路径

(gdb) dir ./temp

断点

断点的设置原理:在程序中设置断点,就是先将该位置的原来的指令保存,然后向该位置写入int 3指令,当执行到int 3的时候,发生软中断,内核会给子进程发出SIGTRAP信号,当然这个信号会被转发给父进程。然后用保存的指令替换int 3,等待恢复运行。

断点的实现原理:就是在指定的位置插入断点指令,当被调试的程序运行到断点的时候,产生SIGTRAP信号,该信号被gdb捕获并进行断点命中判定,当gdb判断出这次SIGTRAP是断点命中之后就会转入等待用户输入进行下一步处理,否则继续。


堆栈

首先理解函数与调用栈的关系,参见:关于函数调用浅析


观察点

查看内存

假设,需要把float变量e按照二进制的方式打印,并且打印单位时一字节。

(gdb) x/4tb &e
0x7fffffffdbd4:    00000000    00000000    00001000    01000001

寄存器
(gdb) info registers
rax            0x4004f0 4195568
rbx            0x0  0
rcx            0x400510 4195600
rdx            0x7fffffffe598   140737488348568
rsi            0x7fffffffe588   140737488348552
rdi            0x1  1
rbp            0x7fffffffe4a0   0x7fffffffe4a0
rsp            0x7fffffffe4a0   0x7fffffffe4a0
r8             0x7ffff7dd6e80   140737351872128
r9             0x0  0
r10            0x7fffffffe2f0   140737488347888
r11            0x7ffff7a3ca40   140737348094528
r12            0x400400 4195328
r13            0x7fffffffe580   140737488348544
r14            0x0  0
r15            0x0  0
rip            0x400503 0x400503 <main+19>
eflags         0x246    [ PF ZF IF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0

查看汇编代码
(gdb) disassemble main
Dump of assembler code for function main:
   0x00000000004004f0 <+0>: push   %rbp
   0x00000000004004f1 <+1>: mov    %rsp,%rbp
   0x00000000004004f4 <+4>: mov    %edi,-0x14(%rbp)
   0x00000000004004f7 <+7>: mov    %rsi,-0x20(%rbp)
   0x00000000004004fb <+11>:    movq   $0x4005a0,-0x8(%rbp)
=> 0x0000000000400503 <+19>:    pop    %rbp
   0x0000000000400504 <+20>:    retq   
End of assembler dump.

常用设置
信号

GDB可以在你调试程序的时候处理任何一种信号,你可以告诉GDB需要处理哪一种信号,你可以要求GDB收到你所指定的信号时,马上停住正在运行的程序,以供你进行调试。

handle <signal> <keywords>
结合core文件调试

使用内核转储(core)的最大好处就是:它能保存问题发生时的状态,只要有问题发生时程序的可执行文件和内核转储,就可以知道进程当时的状态。

gdb a.out xx.core

多线程调试

查看当前进程的所有线程
(gdb) info threads
切换线程栈
(gdb) thread [线程号]
打印所有线程堆栈
thread apply all bt
调试时控制线程切换

在调试多线程程序时,有时候我们希望执行流一直在某个线程执行,而不是切换到其他线程。

那我们可以使用

set scheduler-locking on/off/step
set scheduler-locking on

set scheduler-locking on 可以用来锁定当前线程,只观察这个线程的运行情况, 当锁定这个线程时, 其他线程就处于了暂停状态。
也就是说你在当前线程执行 nextstepuntilfinishreturn 命令时,其他线程是不会运行的。

set scheduler-locking off用于关闭锁定当前线程。

set scheduler-locking step

也是用来锁定当前线程,当且仅当使用 nextstep 命令做单步调试时会锁定当前线程。
如果你使用 untilfinishreturn 等线程内调试命令,但是它们不是单步命令,所以其他线程还是有机会运行的。相比较 on 选项值,step 选项值给为单步调试提供了更加精细化的控制


多进程调试

gdb的调试默认是调试父进程的,但我们可以通过设置来选择调试哪个进程。

(gdb) set follow-fork-mode parent/child

如果选择了parent,这个时候就是进行gdb调试父进程。
如果选择了child,这个时候就是进行gdb调试子进程。
注意,在调试的过程中更改mode是没有用的,这种设置只对下一次fork后起作用。


参考
[1] http://www.unknownroad.com/rtfm/gdbtut/gdbtoc.html
[2] http://www.cnblogs.com/pannengzhi/p/5203467.html
[3] https://zhuanlan.zhihu.com/p/74897601

上一篇下一篇

猜你喜欢

热点阅读