使用MDB查看變量的值(1)

 

使用MDB查看變量的值(1

[email protected]

 

本節描述使用MDBcore文件中變量的基本知識

基本概念:

    一般程序發生coredump80%的可能是由於參數的值不對造成的(其他可能是堆棧溢出、多線程等問題造成的)。對於可以復現的問題,一般拿到函數堆棧,通過走讀代碼基本上就可以定位。對於無法復現的問題,大部分情況需要通過查看變量的值來定位。(注:網上很多文章都是介紹通過反彙編定位哪條語句引起的coredump,個人認爲這種方法比較繁瑣(需要重新編譯),且對優化後的程序用處不大,本文就不討論了。)

      變量可以分爲兩類,一類是基本類型,例如int等,可以在函數堆棧裏直接看到值;另一類是類類型,包括stringSTL和用戶自定義類型等,這種類型在函數堆棧裏會顯示它的地址。

    使用“地址/格式”這種形式,可以查看地址中保存的值。例如,有代碼:

    int *p = new int(2010);

      假設p=0x8011320,則使用8011320/D,就可以顯示2010。常用的格式如下:

X:十六進制int(一般用來顯示地址)

D:十進制有符號int

U:十進制無符號int

E:十進制無符號long long

e:十進制有符號long long

s:顯示字符串

    查看變量的值時,一定要有源代碼(至少要有函數聲明),否則就無法知道變量的類型,許多地址取值操作就無法實施。

 

實例:

 

OSSolaris10x86

編譯器:Sun Studio 11

1)  看實參的值,普通函數,參數爲內置類型(int類型)。

有如下程序:

 

編譯(CC –o 1 coretest.cpp)、運行,會產生core文件。

使用MDB

bash-3.00# mdb core

Loading modules: [ libc.so.1 ld.so.1 ]

> $G

C++ symbol demangling enabled

> $C

080471f4 libc.so.1`_lwp_kill+7(1, 6)

0804720c libc.so.1`raise+0x1f(6)

08047254 libc.so.1`abort+0xcd(fee28ef0, a8, 804727c, fee14653, fee28ef0,

fee29a20)

08047264 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,

80472ac, fefc0568, 80472ac, fee14ab9)

0804727c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,

fee1537d, 0)

080472ac libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,

fee28ef0, 0, 805092a, 80472e4)

080472c8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)

080472e4 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050b78, 0)

0804730c void f+0x37(1)

0804732c main+0x1f(1, 8047358, 8047360)

0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)

 其中1即爲參數i的值。

 

2)  看實參的值,普通函數,參數爲類類型。

有如下程序:

 

編譯(CC –o 1 coretest2.cpp)、運行,會產生core文件。

使用MDB

bash-3.00# mdb core

Loading modules: [ libc.so.1 ld.so.1 ]

> $G

C++ symbol demangling enabled

> $C

080471f4 libc.so.1`_lwp_kill+7(1, 6)

0804720c libc.so.1`raise+0x1f(6)

08047254 libc.so.1`abort+0xcd(fee28ef0, a8, 804727c, fee14653, fee28ef0,

fee29a20)

08047264 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,

80472ac, fefc0568, 80472ac, fee14ab9)

0804727c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,

fee1537d, 0)

080472ac libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,

fee28ef0, 0, 805092a, 80472e0)

080472c8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)

080472e0 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050b80, 0)

08047308 void f+0x37(8047320)

0804732c main+0x26(1, 8047358, 8047360)

0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)

因爲函數原型爲void f(const A& a)a爲引用類型,所以8047320a的地址(16進制),即m_i的地址,所以m_i的值爲:

> 8047320/X

0x8047320:      3

m_j的地址爲m_i的地址加4,所以m_j的值爲:

> 8047320+4/X

0x8047324:      7

 

3)  看實參的值,普通函數,參數爲類類型(有虛函數表)。

有如下程序:

 

編譯(CC –o 1 coretest3.cpp)、運行,會產生core文件。

 

使用MDB

bash-3.00# mdb core

Loading modules: [ libc.so.1 ld.so.1 ]

> $G

C++ symbol demangling enabled

> $C

080471e4 libc.so.1`_lwp_kill+7(1, 6)

080471fc libc.so.1`raise+0x1f(6)

08047244 libc.so.1`abort+0xcd(fee28ef0, a8, 804726c, fee14653, fee28ef0,

fee29a20)

08047254 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,

804729c, fefc0568, 804729c, fee14ab9)

0804726c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,

fee1537d, 0)

0804729c libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,

fee28ef0, 0, 8050a4a, 80472d8)

080472b8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)

080472d8 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050d58, 0)

08047300 void f+0x37(804731c)

0804732c main+0x32(1, 8047358, 8047360)

0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)

因爲函數原型爲void f(const A& a)a爲引用類型,所以804731ca的地址(16進制)。因爲類型A含有虛函數,所以804731c指向的內容8060fa4爲虛函數表的地址:

> 804731c/X

0x804731c:      8060fa4

> 8060fa4/X

1`__1cBAG__vtbl_:

1`A::__vtbl:    8050d80

> 8060fa4::nm

Value      Size       Type  Bind  Other Shndx    Name

0x08060fa4|0x0000000c|OBJT |WEAK |0x0  |18      |1`__1cBAG__vtbl_

m_i的地址爲a的地址加4,所以m_i的值爲:

> 804731c+4/X

0x8047320:      3

m_j的地址爲m_i的地址加4,所以m_j的值爲:

> 804731c+4+4/X

0x8047324:      7

 

4)  看實參的值,成員函數,參數爲類類型(有虛函數表)。

有如下程序:

 

編譯(CC –o 1 –g coretest4.cpp)、運行,會產生core文件。

 

使用MDB

bash-3.00# mdb core

Loading modules: [ libc.so.1 ld.so.1 ]

> $G

C++ symbol demangling enabled

> $C

080471e4 libc.so.1`_lwp_kill+7(1, 6)

080471fc libc.so.1`raise+0x1f(6)

08047244 libc.so.1`abort+0xcd(fee28ef0, a8, 804726c, fee14653, fee28ef0,

fee29a20)

08047254 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,

804729c, fefc0568, 804729c, fee14ab9)

0804726c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,

fee1537d, 0)

0804729c libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,

fee28ef0, 0, 8050a4a, 80472d0)

080472b8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)

080472d0 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050d94, 0)

080472f8 void B::f+0x37(804731b, 804731c)

0804732c main+0x39(1, 8047358, 8047360)

0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)

因爲f爲非靜態成員函數,所以第一個參數(804731b)爲this指針,第二個參數(804731c)爲a的地址,其他變量查看方法同3

注:如果f爲靜態成員函數,則不存在this指針。

發佈了105 篇原創文章 · 獲贊 5 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章