GDB調試C++類
創(chuàng)新互聯(lián)公司成都網(wǎng)站建設按需網(wǎng)站制作,是成都網(wǎng)站維護公司,為成都高空作業(yè)車租賃提供網(wǎng)站建設服務,有成熟的網(wǎng)站定制合作流程,提供網(wǎng)站定制設計服務:原型圖制作、網(wǎng)站創(chuàng)意設計、前端HTML5制作、后臺程序開發(fā)等。成都網(wǎng)站改版熱線:028-86922220
Linux上調試常用的工具就是gdb了。借助學習C++虛函數(shù)表和內存布局的機會順便學習下gdb常規(guī)調試技巧。
一,測試用例
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() { /* 靜態(tài)函數(shù)訪問 */ Base::static_func1(); /* 創(chuàng)建對象 */ Base bb( 57 ); /* 非靜態(tài)函數(shù)訪問 */ bb.non_static_func1(); /* 虛函數(shù)訪問 */ bb.virtual_func1(); } int main( int argc, char *argv[] ) { test1(); return 0; }
二,調試
1,gdb調試前需編譯生成可執(zhí)行文件,并且需把調試信息加到可執(zhí)行文件中。-g參數(shù)可以做到這點。使用方法為:g++ -g szyu_test_gdb.cpp(默認生成a.out可執(zhí)行文件)
2,啟動gdb調試:gdb a.out
3,設置斷點,可獲取運行時的堆棧信息。
分別對以下位置設置了斷點:
1)構造函數(shù):Base( int v )
2)虛析構函數(shù):virtual ~Base()
3)靜態(tài)函數(shù)調用:bb.static_func1()
4)非靜態(tài)函數(shù)調用:bb.non_static_func1()
5)虛函數(shù)調用:bb.virtual_func1()
4,運行程序,遇到第一個斷點:靜態(tài)函數(shù)調用。單步跟蹤s(step)命令進入函數(shù)內部,并打印地址如下:
5,c(continue)恢復程序運行,接下來程序停在第二斷點處,即Base(int v)構造函數(shù)處。打印Base類對象bb如下:
由圖可以類對象的地址為:0x7fffffffe320
對對象首地址進行解引用得到地址:0x400cb0即為虛函數(shù)表地址,故可知在該編譯器中的虛函數(shù)表位于對象實例的最前端。
從打印的Base類對象可知,此時虛函數(shù)表已創(chuàng)建,且虛函數(shù)表地址為0x400cb0。對于靜態(tài)成員和非靜態(tài)成員都已初始化好了。此時獲取虛函數(shù)表中的內容如下所示:
由于虛函數(shù)表是二級指針。所以使用void **轉換。再使用解引用運算符變成一級指針。
其中還涉及到set print array,@和/a三個知識點:
1)默認數(shù)組顯示是關閉狀態(tài)的(即打印數(shù)組時,每個元素則以逗號分隔)。打開數(shù)組顯示狀態(tài)后,每個元素占一行打印。
2)p /a 打印語句中a只是參數(shù)選項之一,常見該參數(shù)如下:
x 按十六進制格式顯示變量。
d 按十進制格式顯示變量。
u 按十六進制格式顯示無符號整型。
o 按八進制格式顯示變量。
t 按二進制格式顯示變量。
a 按十六進制格式顯示變量。
c 按字符格式顯示變量。
f 按浮點數(shù)格式顯示變量。
3)“@”的左邊是第一個內存的地址的值,“@”的右邊則你你想查看內存的長度。上圖中的4代表打印出四段內存長度。此處由于虛函數(shù)表中總共存了三個虛函數(shù)內存段地址,故最后一個值是隨機數(shù)。
為了支持RTTI(Run Time Type Identification,運行時類型識別),在虛函數(shù)表前存放了type_info指針。
而靜態(tài)成員變量和非靜態(tài)成員變量獲取如下:
6,c(continue)繼續(xù)運行,接下來程序停留在第三個斷點處,即非靜態(tài)方法調用。
7,c(continue)繼續(xù)運行,接下來程序停留在第四個斷點處,即虛函數(shù)調用。
由打印出來的虛函數(shù)地址可知:該地址與虛函數(shù)表中存的地址一致。
8,c(continue)繼續(xù)運行,接下來程序停留在第五個斷點處,即虛析構函數(shù)。
通過info line查看地址與虛函數(shù)表一致。
本文gdb調試命令主要參考:http://blog.csdn.net/haoel/article/details/2879
網(wǎng)站欄目:[C++]GDB調試C++類
轉載注明:http://www.chinadenli.net/article28/ighscp.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供用戶體驗、微信小程序、App開發(fā)、網(wǎng)站導航、云服務器、建站公司
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)