91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

[C++]GDB調試C++類

發布時間:2020-08-02 15:19:03 來源:網絡 閱讀:16407 作者:風子余 欄目:編程語言

GDB調試C++類

    Linux上調試常用的工具就是gdb了。借助學習C++虛函數表和內存布局的機會順便學習下gdb常規調試技巧。

一,測試用例

1,C++頭文件(szyu_test_gdb.h)

/******************************
*
* Author : szyu
*
* Date : 2016.10.25
*
********************************/

#ifndef __SZYU_GDB__
#define __SZYU_GDB__

#include <iostream>

class Base
{
public:
    Base() { };
    Base( int v ) : non_static_member1( v ) { };
    virtual ~Base() { };

public:
    void
    non_static_func1()
    {   
        std::cout << "In non_static_func1()" << std::endl;
    }   

    static void
    static_func1()
    {
        std::cout << "In static_func1()" << std::endl;
    }

    virtual void
    virtual_func1()
    {
        std::cout << "In virtual_func1()" << std::endl;
    }

private:
    int non_static_member1;
    static int static_member1;
};

int Base::static_member1 = 99;

#endif

2,C++測試用例(szyu_test_gdb.cpp)

/************************
*
* Author : szyu
*
* Date : 2016.10.25
*
******************************/

#include "szyu_test_gdb.h"

void
test1()
{
    /* 靜態函數訪問 */
    Base::static_func1();
    /* 創建對象 */
    Base bb( 57 );
    /* 非靜態函數訪問 */
    bb.non_static_func1();

    /* 虛函數訪問 */
    bb.virtual_func1();
}

int
main( int argc, char *argv[] )
{
    test1();

    return 0;
}

二,調試

1,gdb調試前需編譯生成可執行文件,并且需把調試信息加到可執行文件中。-g參數可以做到這點。使用方法為:g++  -g  szyu_test_gdb.cpp(默認生成a.out可執行文件)

2,啟動gdb調試:gdb  a.out

[C++]GDB調試C++類

3,設置斷點,可獲取運行時的堆棧信息。

分別對以下位置設置了斷點:

1)構造函數:Base( int v )

2)虛析構函數:virtual ~Base()

3)靜態函數調用:bb.static_func1()

4)非靜態函數調用:bb.non_static_func1()

5)虛函數調用:bb.virtual_func1()

[C++]GDB調試C++類

4,運行程序,遇到第一個斷點:靜態函數調用。單步跟蹤s(step)命令進入函數內部,并打印地址如下:

[C++]GDB調試C++類

5,c(continue)恢復程序運行,接下來程序停在第二斷點處,即Base(int v)構造函數處。打印Base類對象bb如下:

[C++]GDB調試C++類

由圖可以類對象的地址為:0x7fffffffe320

對對象首地址進行解引用得到地址:0x400cb0即為虛函數表地址,故可知在該編譯器中的虛函數表位于對象實例的最前端。

從打印的Base類對象可知,此時虛函數表已創建,且虛函數表地址為0x400cb0。對于靜態成員和非靜態成員都已初始化好了。此時獲取虛函數表中的內容如下所示:

[C++]GDB調試C++類

由于虛函數表是二級指針。所以使用void **轉換。再使用解引用運算符變成一級指針。

其中還涉及到set print array,@和/a三個知識點:

1)默認數組顯示是關閉狀態的(即打印數組時,每個元素則以逗號分隔)。打開數組顯示狀態后,每個元素占一行打印。

2)p /a 打印語句中a只是參數選項之一,常見該參數如下:

    x  按十六進制格式顯示變量。
    d  按十進制格式顯示變量。
    u  按十六進制格式顯示無符號整型。
    o  按八進制格式顯示變量。
    t  按二進制格式顯示變量。 
    a  按十六進制格式顯示變量。
    c  按字符格式顯示變量。
    f  按浮點數格式顯示變量。

3)“@”的左邊是第一個內存的地址的值,“@”的右邊則你你想查看內存的長度。上圖中的4代表打印出四段內存長度。此處由于虛函數表中總共存了三個虛函數內存段地址,故最后一個值是隨機數。

為了支持RTTI(Run Time Type Identification,運行時類型識別),在虛函數表前存放了type_info指針。

[C++]GDB調試C++類


[C++]GDB調試C++類靜態成員變量和非靜態成員變量獲取如下:

[C++]GDB調試C++類

6,c(continue)繼續運行,接下來程序停留在第三個斷點處,即非靜態方法調用。

[C++]GDB調試C++類

7,c(continue)繼續運行,接下來程序停留在第四個斷點處,即虛函數調用。

[C++]GDB調試C++類

由打印出來的虛函數地址可知:該地址與虛函數表中存的地址一致。

8,c(continue)繼續運行,接下來程序停留在第五個斷點處,即虛析構函數。

[C++]GDB調試C++類

通過info line查看地址與虛函數表一致。


本文gdb調試命令主要參考:http://blog.csdn.net/haoel/article/details/2879

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沈丘县| 军事| 桐庐县| 托克逊县| 凯里市| 南郑县| 阿坝| 曲松县| 天门市| 肇东市| 专栏| 桓台县| 象山县| 镇康县| 尚志市| 南木林县| 厦门市| 西青区| 天长市| 岫岩| 砀山县| 南宁市| 师宗县| 黔西| 襄汾县| 古田县| 丰城市| 喜德县| 大悟县| 嘉荫县| 鄂托克前旗| 锡林郭勒盟| 石楼县| 额敏县| 项城市| 新干县| 丰原市| 衡山县| 石狮市| 冕宁县| 保德县|