1) 直接獲取異常的相關調用函數,在相應函數處設置斷點。
2) 利用gdb的catch throw/catch。(程序執行後,方有效)
如何獲取C++調用函數信息?
寫一個簡單C++程序,讓程序因異常而終止,bt查看調用棧,即可知道異常相關函數。
一個簡單程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#include
<iostream> #include
<string> //
#include <exception> #include
<stdexcept> void ter_handler(){ printf ( "custom
handler\n" ); } void test(){ throw std::runtime_error( "test
function" ); } int main( int argc,
char **
argv) { std::set_terminate(__gnu_cxx::__verbose_terminate_handler); //
std::set_terminate(ter_handler); try { //
throw 5; throw std::runtime_error( "test
error" ); } catch (...){ printf ( "catch
exception\n" ); } test(); return 0; } |
g++ -o test exception.cc
gdb ./test
Program received signal SIGABRT, Aborted.
0x0000003cf592e2ed in raise () from /lib64/tls/libc.so.6
(gdb) bt
#0 0x0000003cf592e2ed in raise () from /lib64/tls/libc.so.6
#1 0x0000003cf592fa3e in abort () from /lib64/tls/libc.so.6
#2 0x0000003cf86b1138 in __gnu_cxx::__verbose_terminate_handler () from /usr/lib64/libstdc++.so.6
#3 0x0000003cf86af166 in __cxa_call_unexpected () from /usr/lib64/libstdc++.so.6
#4 0x0000003cf86af193 in std::terminate () from /usr/lib64/libstdc++.so.6
#5 0x0000003cf86af293 in __cxa_throw () from /usr/lib64/libstdc++.so.6
#6 0x0000000000400e9f in test ()
#7 0x0000000000400f9d in main ()
從上述調用棧,可以得知異常由__cxa_throw ()拋出,可在該函數處設置斷點,從而得知“異常出自哪裏”。
測試環境:
Linux bclnx64 2.6.9-34.ELsmp #1 SMP
GNU gdb Red Hat Linux (6.3.0.0-1.96rh)
Copyright 2004 Free Software Foundation, Inc.
上述給出的獲取異常調用函數信息的方法,應該和操作系統和調試器無關,其他平臺類似。
1) 直接獲取異常的相關調用函數,在相應函數處設置斷點。
利用前一步驟的信息,直接b __cxa_throw,即可設置有效斷點。
2) 利用gdb的catch throw/catch
該方法也很通用,但有一個需要注意的地方:在程序執行之前,catch throw/catch是無效的,需要在程序執行之後(先在main處設置斷點),使用catch throw纔有效。
簡單示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
nochen@bclnx64
~/test$ gdb ./test GNU
gdb Red Hat Linux (6.3.0.0-1.96rh) Copyright
2004 Free Software Foundation, Inc. (gdb)
b __cxa_throw Function
"__cxa_throw" not
defined. Make
breakpoint pending on future shared library load? (y or [n]) y Breakpoint
1 (__cxa_throw) pending. (gdb)
r Starting
program: /home/nochen/test/test (no
debugging symbols found) Breakpoint
2 at 0x3cf86af230 Pending
breakpoint "__cxa_throw" resolved Breakpoint
2, 0x0000003cf86af230 in __cxa_throw () from /usr/lib64/libstdc++.so.6 (gdb)
bt #0
0x0000003cf86af230 in __cxa_throw () from /usr/lib64/libstdc++.so.6 #1
0x0000000000400f5b in main () (gdb)
c Continuing. catch exception Breakpoint
2, 0x0000003cf86af230 in __cxa_throw () from /usr/lib64/libstdc++.so.6 (gdb)
bt #0
0x0000003cf86af230 in __cxa_throw () from /usr/lib64/libstdc++.so.6 #1
0x0000000000400e9f in test () #2
0x0000000000400f9d in main () (gdb)
c Continuing. terminate
called after throwing an instance of 'std::runtime_error' what():
test function Program
received signal SIGABRT,
Aborted. 0x0000003cf592e2ed
in raise ()
from /lib64/tls/libc.so.6 (gdb)
q The
program is running. Exit anyway? (y or n) y =================================== nochen@bclnx64
~/test$ gdb ./test (gdb)
b main Breakpoint
1 at 0x400ea4 (gdb)
r Starting
program: /home/nochen/test/test (no
debugging symbols found) Breakpoint
1, 0x0000000000400ea4 in main () (gdb)
catch throw Catchpoint
2 ( throw ) (gdb)
c Continuing. Catchpoint
2 (exception thrown) 0x0000003cf86af230
in __cxa_throw () from /usr/lib64/libstdc++.so.6 (gdb)
bt #0
0x0000003cf86af230 in __cxa_throw () from /usr/lib64/libstdc++.so.6 #1
0x0000000000400f5b in main () (gdb)
c Continuing. catch exception Catchpoint
2 (exception thrown) 0x0000003cf86af230
in __cxa_throw () from /usr/lib64/libstdc++.so.6 (gdb)
bt #0
0x0000003cf86af230 in __cxa_throw () from /usr/lib64/libstdc++.so.6 #1
0x0000000000400e9f in test () #2
0x0000000000400f9d in main () (gdb)
c Continuing. terminate
called after throwing an instance of 'std::runtime_error' what():
test function Program
received signal SIGABRT,
Aborted. 0x0000003cf592e2ed
in raise ()
from /lib64/tls/libc.so.6 (gdb)
|