[C++]GDB調(diào)試C++類(lèi)

GDB調(diào)試C++類(lèi)

創(chuàng)新互聯(lián)公司成都網(wǎng)站建設(shè)按需網(wǎng)站制作,是成都網(wǎng)站維護(hù)公司,為成都高空作業(yè)車(chē)租賃提供網(wǎng)站建設(shè)服務(wù),有成熟的網(wǎng)站定制合作流程,提供網(wǎng)站定制設(shè)計(jì)服務(wù):原型圖制作、網(wǎng)站創(chuàng)意設(shè)計(jì)、前端HTML5制作、后臺(tái)程序開(kāi)發(fā)等。成都網(wǎng)站改版熱線(xiàn):028-86922220

    Linux上調(diào)試常用的工具就是gdb了。借助學(xué)習(xí)C++虛函數(shù)表和內(nèi)存布局的機(jī)會(huì)順便學(xué)習(xí)下gdb常規(guī)調(diào)試技巧。

一,測(cè)試用例

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++測(cè)試用例(szyu_test_gdb.cpp)

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

#include "szyu_test_gdb.h"

void
test1()
{
    /* 靜態(tài)函數(shù)訪(fǎng)問(wèn) */
    Base::static_func1();
    /* 創(chuàng)建對(duì)象 */
    Base bb( 57 );
    /* 非靜態(tài)函數(shù)訪(fǎng)問(wèn) */
    bb.non_static_func1();

    /* 虛函數(shù)訪(fǎng)問(wèn) */
    bb.virtual_func1();
}

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

    return 0;
}

二,調(diào)試

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

2,啟動(dòng)gdb調(diào)試:gdb  a.out

[C++]GDB調(diào)試C++類(lèi)

3,設(shè)置斷點(diǎn),可獲取運(yùn)行時(shí)的堆棧信息。

分別對(duì)以下位置設(shè)置了斷點(diǎn):

1)構(gòu)造函數(shù):Base( int v )

2)虛析構(gòu)函數(shù):virtual ~Base()

3)靜態(tài)函數(shù)調(diào)用:bb.static_func1()

4)非靜態(tài)函數(shù)調(diào)用:bb.non_static_func1()

5)虛函數(shù)調(diào)用:bb.virtual_func1()

[C++]GDB調(diào)試C++類(lèi)

4,運(yùn)行程序,遇到第一個(gè)斷點(diǎn):靜態(tài)函數(shù)調(diào)用。單步跟蹤s(step)命令進(jìn)入函數(shù)內(nèi)部,并打印地址如下:

[C++]GDB調(diào)試C++類(lèi)

5,c(continue)恢復(fù)程序運(yùn)行,接下來(lái)程序停在第二斷點(diǎn)處,即Base(int v)構(gòu)造函數(shù)處。打印Base類(lèi)對(duì)象bb如下:

[C++]GDB調(diào)試C++類(lèi)

由圖可以類(lèi)對(duì)象的地址為:0x7fffffffe320

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

從打印的Base類(lèi)對(duì)象可知,此時(shí)虛函數(shù)表已創(chuàng)建,且虛函數(shù)表地址為0x400cb0。對(duì)于靜態(tài)成員和非靜態(tài)成員都已初始化好了。此時(shí)獲取虛函數(shù)表中的內(nèi)容如下所示:

[C++]GDB調(diào)試C++類(lèi)

由于虛函數(shù)表是二級(jí)指針。所以使用void **轉(zhuǎn)換。再使用解引用運(yùn)算符變成一級(jí)指針。

其中還涉及到set print array,@和/a三個(gè)知識(shí)點(diǎn):

1)默認(rèn)數(shù)組顯示是關(guān)閉狀態(tài)的(即打印數(shù)組時(shí),每個(gè)元素則以逗號(hào)分隔)。打開(kāi)數(shù)組顯示狀態(tài)后,每個(gè)元素占一行打印。

2)p /a 打印語(yǔ)句中a只是參數(shù)選項(xiàng)之一,常見(jiàn)該參數(shù)如下:

    x  按十六進(jìn)制格式顯示變量。
    d  按十進(jìn)制格式顯示變量。
    u  按十六進(jìn)制格式顯示無(wú)符號(hào)整型。
    o  按八進(jìn)制格式顯示變量。
    t  按二進(jìn)制格式顯示變量。 
    a  按十六進(jìn)制格式顯示變量。
    c  按字符格式顯示變量。
    f  按浮點(diǎn)數(shù)格式顯示變量。

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

為了支持RTTI(Run Time Type Identification,運(yùn)行時(shí)類(lèi)型識(shí)別),在虛函數(shù)表前存放了type_info指針。

[C++]GDB調(diào)試C++類(lèi)

[C++]GDB調(diào)試C++類(lèi)而靜態(tài)成員變量和非靜態(tài)成員變量獲取如下:

[C++]GDB調(diào)試C++類(lèi)

6,c(continue)繼續(xù)運(yùn)行,接下來(lái)程序停留在第三個(gè)斷點(diǎn)處,即非靜態(tài)方法調(diào)用。

[C++]GDB調(diào)試C++類(lèi)

7,c(continue)繼續(xù)運(yùn)行,接下來(lái)程序停留在第四個(gè)斷點(diǎn)處,即虛函數(shù)調(diào)用。

[C++]GDB調(diào)試C++類(lèi)

由打印出來(lái)的虛函數(shù)地址可知:該地址與虛函數(shù)表中存的地址一致。

8,c(continue)繼續(xù)運(yùn)行,接下來(lái)程序停留在第五個(gè)斷點(diǎn)處,即虛析構(gòu)函數(shù)。

[C++]GDB調(diào)試C++類(lèi)

通過(guò)info line查看地址與虛函數(shù)表一致。


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

網(wǎng)站欄目:[C++]GDB調(diào)試C++類(lèi)
轉(zhuǎn)載注明:http://muchs.cn/article28/ighscp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶(hù)體驗(yàn)、微信小程序App開(kāi)發(fā)、網(wǎng)站導(dǎo)航、云服務(wù)器、建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)