gdb 工具的簡單使用

gdb工具是個頗有用的工具.常常用於咱們項目的調試使用。docker

首先咱們來啓動一個鏡像:sass

docker run -it --privileged=true thrift/new  /bin/bash
複製代碼

1. 咱們看下今天要分析的代碼:

#include "stdio.h"

int getSum(int param_one,int param_two)
{
   return param_one+param_two;
}

int main()
{
   int a = 10;
   int b = 5;
   int sum = getSum(a,b);
   printf("%d",sum);
}
複製代碼

使用gcc編譯:bash

gcc -g -o test test.c
複製代碼

加上 -g 選項即爲了程序編譯後的程序中保留調試符號信息數據結構

若是發佈代碼的話,能夠使用命令來移除調試符號信息:函數

strip test
複製代碼

2. gdb 實操

函數級別斷點

gdb test

#break指令 在main函數處斷點
b main

#在getSum函數處斷點
b getSum
複製代碼

接下來咱們看下執行流程:工具

#run r命令重啓程序將在斷點處停下
r

Breakpoint 1, main () at test.c:10
10	   int a = 10;

複製代碼
#continue 繼續向下執行
c 

Breakpoint 2, getSum (param_one=10, param_two=5) at test.c:5
5	   return param_one+param_two;
複製代碼

咱們看到已經執行到咱們的第二個斷點上來了。ui

固然,還有更加靈活的斷點方式,具體到咱們的代碼某行.spa

#在咱們的例子代碼中,斷點第五行代碼
b test.c:5

Breakpoint 1 at 0x400527: file test.c, line 5.

#運行run
r
Breakpoint 1, getSum (param_one=10, param_two=5) at test.c:5
5	   return param_one+param_two;
複製代碼

斷點是爲了更好的調試咱們的程序, 可是咱們發現這樣調試來信息仍是比較少, 若是想了解調用的堆棧信息, 咱們繼續看下面的指令調試

backtrace 命令(簡寫爲 bt)code

(gdb)b test.c:5

(gdb)r

(gdb) bt
#0 getSum (param_one=10, param_two=5) at test.c:5
#1 0x0000000000400556 in main () at test.c:12
複製代碼

咱們看到了調用的堆棧信息 main()->getSum()

函數調用爲棧的數據結構存儲形式

咱們看到只有兩層棧的調用,咱們能夠使用frame切換到指定的棧.

#frame 堆棧編號
f 1

#1 0x0000000000400556 in main () at test.c:12
12	   int sum = getSum(a,b);
複製代碼

咱們能夠看到具體的調用方式

當咱們斷點或切換到某個堆棧的時候,還想更詳細的看當前斷點代碼

# list l 當前斷點處的代碼

#切換棧
(gdb) f 1

(gdb) l
8	int main()
9	{
10	   int a = 10;
11	   int b = 5;
12	   int sum = getSum(a,b);
13	   printf("%d",sum);
14	}
複製代碼

查看當前運行的變量值(print)

#打印params_two的值
p params_two 
$1 = 10
複製代碼

咱們還能夠手動修改當前運行變量

p params_two=50
複製代碼

查看咱們打了哪些斷點

info b

Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400539 in main at test.c:10
2       breakpoint     keep y   0x0000000000400527 in getSum at test.c:5
複製代碼

禁用/啓用某個斷點

disable 斷點編號
enable 斷點編號
複製代碼

使用delete命令刪除斷點

(gdb) delete

Delete all breakpoints? (y or n) y
複製代碼

查看斷點的彙編指令

(gdb) disassemble

Dump of assembler code for function main:
   0x0000000000400531 <+0>:	push   %rbp
   0x0000000000400532 <+1>:	mov    %rsp,%rbp
   0x0000000000400535 <+4>:	sub    $0x10,%rsp
=> 0x0000000000400539 <+8>:	movl   $0xa,-0x4(%rbp)
   0x0000000000400540 <+15>:	movl   $0x5,-0x8(%rbp)
   0x0000000000400547 <+22>:	mov    -0x8(%rbp),%edx
   0x000000000040054a <+25>:	mov    -0x4(%rbp),%eax
   0x000000000040054d <+28>:	mov    %edx,%esi
   0x000000000040054f <+30>:	mov    %eax,%edi
   0x0000000000400551 <+32>:	callq  0x40051d <getSum>
   0x0000000000400556 <+37>:	mov    %eax,-0xc(%rbp)
   0x0000000000400559 <+40>:	mov    -0xc(%rbp),%eax
   0x000000000040055c <+43>:	mov    %eax,%esi
   0x000000000040055e <+45>:	mov    $0x400600,%edi
   0x0000000000400563 <+50>:	mov    $0x0,%eax
   0x0000000000400568 <+55>:	callq  0x400400 <printf@plt>
   0x000000000040056d <+60>:	leaveq 
   0x000000000040056e <+61>:	retq   
End of assembler dump.
複製代碼

使用watch監控某個變量的變化

(gdb) b main 

(gdb) r

(gdb) watch sum

Old value = 32767
New value = 15
main () at test.c:13
13	   printf("%d",sum);
複製代碼

先到這裏吧, 等接下來咱們再研究下多進程的代碼如何使用gdb調試。

相關文章
相關標籤/搜索