gdb attach使用

進入調試:

ps命令查看進程id。
執行gdb attach pid即可調試正在運行的程序。
info proc顯示當前程序可執行文件相關信息(name,pwd)

斷點相關:

b pkt.c:22(在pkt.c文件的22行打斷點)
b eth_rcv (在函數eth_rcv入口打斷點)
info b;顯示當前所有斷點;
d num;刪除斷點num;
n num;向後執行num步

bt顯示當前函數的調用過程;

打印變量值:

p temp;默認十進制打印
p /x temp;按十六進制打印
x 按十六進制格式顯示變量。
d 按十進制格式顯示變量。
u 按十六進制格式顯示無符號整型。
o 按八進制格式顯示變量。
t 按二進制格式顯示變量。
a 按十六進制格式顯示變量。
c 按字符格式顯示變量。
f 按浮點數格式顯示變量。
顯示變量類型:whatis var;顯示var變量的類型
顯示變量的結構體成員: ptype var ;顯示var類型結構體的成員

gdb中的變量:

程序的變量和gdb的變量是可以交互的,gdb中的變量以 i。

set $i=0
print a[$i++]

即可實現打印以a地址起始的內存中的值。

條件進入斷點:

如:b arp_rcv if index = 1234(當index=1234時進入斷點,注意是單等號)

查看內存:

x /x 以十六進制輸出
x /d 以十進制輸出
x /c 以單字符輸出
x /i 反彙編 – 通常,我們會使用 x/10i ip20 ip是指令寄存器)
x /s 以字符串輸出

打印指定內存起始100字節內容:
x /100ua pkt->data

設置臨時變量:

set i=msg>msgdataprint i打印變量msg->msg_data指針;
ptype $i 打印msg->msg_data類型

command命令:

自動化調試,把一組gdb的命令打包。執行到斷點處時自動執行一系列命令。
如:

(gdb) b ftm_pkt_rcv_from_app
Breakpoint 1 at 0x191a8: file ftm_pkt.c, line 204.
(gdb) command 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>p /x pmesg
>p /x pmesg->msg_data
>
>end
(gdb) c
Continuing.

Breakpoint 1, ftm_pkt_rcv_from_app (pmesg=pmesg@entry=0x45b2c) at ftm_pkt.c:204
204     ftm_pkt.c: No such file or directory.
$1 = 0x45b2c
$2 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, 0x59, 0x6d, 0x38, 0x9c, 0x74, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x12, 0x0, 0x0, 0x0,
  0x0, 0x0, 0x10, 0x0, 0x12, 0x0, 0x0, 0x47, 0x1, 0x3d, 0x0, 0xa, 0x1, 0x0, 0x8, 0x4, 0x0, 0x1, 0x0, 0x0, 0x0, 0x64, 0x1e, 0x81, 0x1, 0x2, 0x3, 0x4c,
  0xcc, 0x6a, 0x70, 0xf4, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x45, 0x0 <repeats 71 times>, 0x68, 0x61, 0xa, 0x0, 0x76,
  0x61, 0xa, 0x0 <repeats 101 times>, 0x4c, 0xcc, 0x6a, 0x70, 0xf4, 0x17, 0x64, 0x1e, 0x81, 0x1, 0x2, 0x3, 0x8, 0x0, 0x45, 0x0, 0x0, 0x3d, 0x21, 0xd3,
  0x40, 0x0, 0x40, 0x6, 0x8, 0x76, 0xc0, 0xa8, 0xc7, 0x65, 0xc0, 0xa8, 0xc7, 0xbb, 0xa, 0x5a, 0x22, 0x43, 0x29, 0x29, 0xcd, 0x77, 0x80, 0x2b, 0x6b,
  0x57, 0x50, 0x18, 0x39, 0x8, 0xb5, 0x75, 0x0, 0x0, 0x47, 0x4e, 0x55, 0x20, 0x67, 0x64, 0x62, 0x20, 0x28, 0x47, 0x44, 0x42, 0x29, 0x20, 0x37, 0x2e,
  0x34, 0x2e, 0x31, 0xd, 0xa, 0x78, 0x0 <repeats 202 times>, 0x63, 0x82, 0x53, 0x63, 0x35, 0x1, 0x1, 0x3d, 0x7, 0x1, 0xd4, 0xee, 0x7, 0x27...}
(gdb)

調用函數:

(gdb) call func()
如:
(gdb) call printf(“hello world!\n”);

重定向標準輸出stdout和stderr:

1)先關閉 stdout ,和 stderr 對應的文件描述符。
(gdb) call (int)close(1)
(gdb) call (int)close(2)
2)然後使用以下命令查看一下當前 gdb 窗口所在的虛擬終端。
(gdb) shell tty
/dev/pts/0
3)這時再重新打開 stdout 和 stderr , 把它們和 gdb 窗口所在的虛擬終端關聯起來。
(gdb) p (int)open(“/dev/pts/0”, 2)
1=1(gdb)p(int)open(/dev/pts/0,2) 2 = 2
如果這兩個命令執行結果不是如上結果(1和2),意味着 open 執行失敗,需要重新進行 close 和 open.
4)接下來,重新執行如下命令:
call printf(“helllo world\n”);即可直接在gdb調試窗口看到打印信息。
5)即時刷新 stdout 和 stderr
調用 fflush強制刷新緩衝區:
(gdb)call (int)fflush(0)

另外,如果把這裏的 ”/dev/pts/0” 替換成目標文件名,便可將 stderr 和 stdout 重定向到該文件。

使用shell模式下的命令:

(gdb) define tar
End with a line saying just “end”.

shell tar
end

(gdb)tar 即可使用shell模式下tar命令,類比可得到其他命令。

以下未驗證:

watch div1==div2當變量div1yu div2相等時進入中斷。
info thread 查看當前進程的線程。
thread 切換調試的線程爲指定ID的線程。
break file.c:100 thread all 在file.c文件第100行處爲所有經過這裏的線程設置斷點。
set scheduler-locking off|on|step,這個是問得最多的。在使用step或者continue命令調試當前被調試線程的時候,其他線程也是同時執行的,怎麼只讓被調試程序執行呢?通過這個命令就可以實現這個需求。
off 不鎖定任何線程,也就是所有線程都執行,這是默認值。
on 只有當前被調試程序會執行。
step 在單步的時候,除了next過一個函數的情況(熟悉情況的人可能知道,這其實是一個設置斷點然後continue的行爲)以外,只有當前線程會執行。

發佈了48 篇原創文章 · 獲贊 34 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章