手把手教你玩轉GDB(四)—函數調用棧(call stack)探密

本文是GDB系列的第四篇,感興趣的朋友可以閱讀本系列的前三篇。本文的主要內容是講如何用GDB來查看C/C++程序中函數調用棧(call stack)的相關信息,通過介紹一些相關的命令及其用法,讓讀者朋友能夠循序漸進了解調用棧的各個方面,更好的駕馭程序。下面開始今天的內容。

我們知道,通常一個程序的運行,不外乎是A函數調用B,B函數調用C等等,等所有的調用都完成後,整個程序的運行也就ok了。在這個過程中,每當有新的函數調用,系統都會把該函數的一些信息,包括函數的參數,以及一些寄存器的值等,保存到調用棧(call stack)上。等該函數運行完成後,這些信息再從調用棧上彈出(pop)。如下圖所示,是一個完整的調用棧:


在上圖中,整體叫做調用棧(call stack),每一行叫做一楨(frame)。我們來看看楨信息的組成有哪些:

(1)楨號:調用棧中對楨的一個編號,從0開始,依次增大
(2)PC:Program counter寄存器,指向當前楨中下一條要執行的指令的地址
(3)函數名:當前楨中被調用的函數的名字
(4)參數及傳入的值:當前楨中被調用的函數在調用時傳入的參數及其值
(5)源碼位置:當前楨執行到的源碼位置,格式爲 file:linenum

這裏還有一點需要說明,不知道細心的讀者朋友有沒有發現,foo那一楨沒有PC的地址,GDB通過這樣來標示該楨是當前正在執行到的楨,因此我們通過看調用棧的信息,便可得知程序執行到哪裏了。

讀者朋友有沒有覺得原來函數調用的過程還有這麼多信息可以知道啊,下面我就開始介紹一些GDB命令,通過這些命令你便可以查看到上面介紹的這些信息,甚至更加詳細的信息。

   1.查看調用棧信息:

(1)backtrace: 顯示程序的調用棧信息,可以用bt縮寫
(2)backtrace n: 顯示程序的調用棧信息,只顯示棧頂n楨(frame)
(3)backtrace -n: 顯示程序的調用棧信息,只顯示棧底部n楨(frame)
(4)set backtrace limit n: 設置bt顯示的最大楨層數
(5)where, info stack:都是bt的別名,功能一樣


   2.查看楨信息:

(1)frame n: 查看第n楨的信息, frame可以用f縮寫
(2)frame addr: 查看pc地址爲addr的楨的相關信息
(3)up n: 查看當前楨上面第n楨的信息
(4)down n: 查看當前楨下面第n楨的信息

   3.查看更加詳細的信息:

(1)info frameinfo frame n或者info frame addr

查看指定楨的詳細信息,關於詳細信息的內容,這裏有必要做一個介紹,如下圖所示:

上圖中顯示的信息有:
a. 當前楨的地址: 0xbffff400
b. 當前楨PC: eip = 0×8048516
c. 當前楨函數: bar (test.cpp:16)
d. caller楨的PC: saved eip 0×8048535
e. caller楨的地址: called by frame at 0xbffff420
f. callee楨的地址: caller of frame at 0xbffff3e0
g. 源代碼所用的程序的語言(c/c++): source language c++
h. 當前楨的參數的地址及值: Arglist at 0xbffff3f8, args: name=0×8048621 “jessie”, myname=0x804861c “jack”
i. 當前相中局部變量的地址:Locals at 0xbffff3f8, Previous frame’s sp is 0xbffff400
k. 當前楨中存儲的寄存器: Saved registers: ebp at 0xbffff3f8, eip at 0xbffff3fc

(2)info args:查看當前楨中的參數
(3)info locals:查看當前楨中的局部變量
(4)info catch:查看當前楨中的異常處理器(exception handlers)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章