天天看點

GDB 使用 (四)檢視棧資訊

檢視棧資訊

當程式被停住了,你需要做的第一件事就是檢視程式是在哪裡停住的。當你的程式調用了一個函數,函數的位址,函數參數,函數内的局部變量都會被壓入“棧”(Stack)中。你可以用GDB指令來檢視目前的棧中的資訊。

下面是一些檢視函數調用棧資訊的GDB指令:

backtrace

bt   列印目前的函數調用棧的所有資訊。如:

(gdb) bt

#0 func (n=250) at tst.c:6

#1 0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30

#2 0x400409ed in __libc_start_main () from /lib/libc.so.6

從上可以看出函數的調用棧資訊:__libc_start_main --> main() --> func()

backtrace <n>

bt <n>     n是一個正整數,表示隻列印棧頂上n層的棧資訊。

backtrace <-n>

bt <-n>    -n表一個負整數,表示隻列印棧底下n層的棧資訊。

如果你要檢視某一層的資訊,你需要在切換目前的棧,一般來說,程式停止時,最頂層的棧就是目前棧,如果你要檢視棧下面層的詳細資訊,首先要做的是切換目前棧。

frame <n>

f <n>   n是一個從0開始的整數,是棧中的層編号。比如:frame 0,表示棧頂,frame 1,表示棧的第二層。

up <n>  表示向棧的上面移動n層,可以不打n,表示向上移動一層。

down <n>表示向棧的下面移動n層,可以不打n,表示向下移動一層。

上面的指令,都會列印出移動到的棧層的資訊。如果你不想讓其打出資訊。你可以使用這三個指令:

select-frame <n>   對應于 frame 指令。

up-silently <n>    對應于 up 指令。

down-silently <n>  對應于 down 指令。

檢視目前棧層的資訊,你可以用以下GDB指令:

frame 或 f       會列印出這些資訊:棧的層編号,目前的函數名,函數參數值,函數所在檔案及行号,函數執行到的語句。

info frame

info f

這個指令會列印出更為詳細的目前棧層的資訊,隻不過,大多數都是運作時的内内位址。比如:函數位址,調用函數的位址,被調用函數的位址,目前的函數是由什麼樣的程式語言寫成的、函數參數位址及值、局部變量的位址等等。如:

(gdb) info f

Stack level 0, frame at 0xbffff5d4:

eip = 0x804845d in func (tst.c:6); saved eip 0x8048524

called by frame at 0xbffff60c

source language c.

Arglist at 0xbffff5d4, args: n=250

Locals at 0xbffff5d4, Previous frame's sp is 0x0

Saved registers:

ebp at 0xbffff5d4, eip at 0xbffff5d8

info args   列印出目前函數的參數名及其值。

info locals 列印出目前函數中所有局部變量及其值。

info catch  列印出目前的函數中的異常處理資訊。

繼續閱讀