GDB 调试C++异常

15 篇文章 0 订阅
11 篇文章 0 订阅
http://www.cnblogs.com/zhenjing/archive/2011/06/01/gdb_fork.html

调试C++异常的两种办法:
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)


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值