1. 程式人生 > >【軟體開發底層知識修煉】十七 快速學習GDB除錯四 使用GDB進行函式呼叫棧的檢視

【軟體開發底層知識修煉】十七 快速學習GDB除錯四 使用GDB進行函式呼叫棧的檢視

文章目錄

1 backtrace和frame

一般來說,檢視函式呼叫棧,主要是為了研究函式的呼叫過程。

一般使用下面的命令進行檢視:

  • backtrace

    • 檢視函式的呼叫順序(函式呼叫棧的資訊)
  • frame N

    • 切換到棧編號為N的上下文中(具體棧編號是什麼在下面的實際案例中會有)
  • info frame

    • 檢視當前函式呼叫棧幀的資訊

至於什麼是棧幀資訊,大概就是下圖的樣子,這裡不再多介紹,後面還會有文章學習函式棧幀的概念,或者推薦大家去閱讀程式設計師的自我修養。
在這裡插入圖片描述

  • 上面有一個info frame命令,我們在前幾篇文章已經學習過info的幾個命令。下面再介紹幾個下圖中的info命令:

在這裡插入圖片描述

2 使用GDB進行函式呼叫棧的檢視的實際程式碼案例

我們還是給出以下程式碼,作為這次除錯的程式碼:

frame.c

#include <stdio.h>


int sum(int n)
{
    int ret = 0;
    
    if( n > 0 )
    {
        ret = n + sum(n-1);
    }
    
    return ret;
}


int main()
{
    int s = 0;
    
    s = sum(10);
    
    printf("sum = %d\n", s);
    
    return
0; }

上述程式碼很簡單,sum函式是一個遞迴的求解過程,最終求得1+2+3+…+n

  • 開始進行除錯:
  • 首先將程式編譯,並開啟gdb除錯,這在前幾篇文章已經做過很多次,大概如下圖所示的步驟:
    在這裡插入圖片描述

  • 然後我們再sum函式處打一個斷點,並給出條件,當n==0的時候斷點成立

  • break sum if n==0

  • 檢視斷點是否打上:info breakpoints

  • 執行程式:continue

  • 執行上述幾個步驟後,程式執行到sum函式,並在sum函式遞迴呼叫到n==0的時候停止:
    在這裡插入圖片描述

  • 此時,函式呼叫被中斷,我們現在來使用backtrace命令來檢視之前sum函式的呼叫棧的順序(左側的#0 ,#1…就是棧的編號):
    在這裡插入圖片描述

  • 此時程式執行到n==0,本應該繼續執行sum函式,但是卻被我們的斷點中斷了。所以此時停在最後一層的sum函式遞迴呼叫上。且是停在sum函式中的第6行:

  • 我們連續輸入兩次next,並且檢視當前程式的棧資訊:
    在這裡插入圖片描述

  • 程式執行到13行停下來了,這一行是本該return的。此時的函式棧中 n==0,ret==0,這個ret就差返回給上一層函式呼叫了。

  • 現在我們來使用info registers檢視當前的函式呼叫過程的各個暫存器的值,並使用info frame檢視當前函式呼叫過程的函式棧幀的詳細資訊:
    在這裡插入圖片描述

  • 如上圖,暫存器比較多,這裡我們只關心一個暫存器,ebp,ebp暫存器儲存的是呼叫這個函式的函式(也就是上一個函式,在這裡是#1號棧對應的函式)棧幀基地址(old_ebp)。可以看到,此時的函式棧幀中的ebp地址為0xbffff088。注意你自己執行的話地址可能與我的不一樣。這個地址中儲存的是上一個函式,其實就是1號棧的基地址。我們使用以下命令來檢視該地址處的內容:

  • x /1bx 0xbffff088 //顯示結果為:
    在這裡插入圖片描述

  • 如上圖,紅框內的內容,就是#1號棧的基地址。當然我們可以驗證:連續輸入兩個next命令,程式就會把返回值返回給#1號棧的函式呼叫。那麼此時再輸入info args,n就等於1,因為此時位於#1號棧中。然後在輸入info registers命令檢視#1號棧的暫存器值資訊,如下:
    在這裡插入圖片描述

  • 如上圖,#1號棧中的ebp值為0xbffff0b8,與我們上面在#0號棧中查詢的值是一樣的。這與函式棧幀的理論也是完全相符的。

上面的除錯內容,非常簡單,我們並沒有除錯什麼bug,而是通過上述內容,學習一些除錯的技巧。

3 總結

  • 本節內容學習如何使用GDB檢視函式的呼叫棧資訊。
  • 本文章參考狄泰軟體學院相關課程 想學習的可以加狄泰軟體學院群, 群聊號碼:199546072

  • 學習探討加個人(可以免費幫忙下載CSDN資源):

  • qq:1126137994

  • 微信:liu1126137994

  • 學習交流資源分享qq群:962535112