你的项目中有没有遇到过程序抛异常了,但你却不知道是在哪里抛出来的,项目太大太复杂了,对异常处理又不完善。
现在不用愁了,教你一个小方法,throw 本尊其实是函数__cxa_throw,这次你可以对其打断点了。
示例代码
#include <iostream>
using namespace std;
double division(int a, int b)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
int main ()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
编译、调试
$ g++ -g exception.cc -o exception
$ gdb ./exception
Reading symbols from ./exception...
(gdb) b __cxa_throw
Breakpoint 1 at 0x1150
(gdb) r
Starting program: /mnt/e/doc/knowledge-git/bin/program/exception
Breakpoint 1, 0x00007ffff7e82750 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) bt
#0 0x00007ffff7e82750 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#1 0x00005555555552a9 in division (a=50, b=0) at exception.cc:8
#2 0x00005555555552f7 in main () at exception.cc:20
覆盖__cxa_throw例子
#include <iostream>
#include <dlfcn.h>
#include <execinfo.h>
using namespace std;
typedef void (*cxa_throw_type)(void *, void *, void (*) (void *));
cxa_throw_type orig_cxa_throw = 0;
void load_orig_throw_code()
{
orig_cxa_throw = (cxa_throw_type) dlsym(RTLD_NEXT, "__cxa_throw");
}
extern "C"
void __cxa_throw (void *thrown_exception, void *pvtinfo, void (*dest)(void *)) {
printf(" ################ DETECT A THROWN !!!!! #############\n");
if (orig_cxa_throw == 0)
load_orig_throw_code();
{
static int throw_count = 0;
void *array[10];
size_t size;
size = backtrace(array, 10);
fprintf(stderr, "#### EXCEPTION THROWN (#%d) ####\n", ++throw_count);
backtrace_symbols_fd(array, size, 2); // 2 == stderr
}
orig_cxa_throw(thrown_exception, pvtinfo, dest);
}
double division(int a, int b)
{
if( b == 0 )
{
throw "Division by zero condition!";
}
return (a/b);
}
int main ()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
}catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
编译、调试
$ g++ -g exception.cc -ldl -o exception
$ gdb ./exception
Reading symbols from ./exception...
(gdb) b __cxa_throw
Breakpoint 1 at 0x132e: file exception.cc, line 17.
(gdb) r
Starting program: /mnt/e/doc/knowledge-git/bin/program/exception
Breakpoint 1, __cxa_throw (thrown_exception=0x770000007c, pvtinfo=0x0, dest=0x0) at exception.cc:17
17 void __cxa_throw (void *thrown_exception, void *pvtinfo, void (*dest)(void *)) {
(gdb) bt
#0 __cxa_throw (thrown_exception=0x770000007c, pvtinfo=0x0, dest=0x0) at exception.cc:17
#1 0x000055555555544e in division (a=50, b=0) at exception.cc:39
#2 0x000055555555549c in main () at exception.cc:51
(gdb) c
Continuing.
################ DETECT A THROWN !!!!! #############
#### EXCEPTION THROWN (#1) ####
/mnt/e/doc/knowledge-git/bin/program/exception(__cxa_throw+0x5b)[0x555555555389]
/mnt/e/doc/knowledge-git/bin/program/exception(+0x144e)[0x55555555544e]
/mnt/e/doc/knowledge-git/bin/program/exception(+0x149c)[0x55555555549c]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x7ffff7bec0b3]
/mnt/e/doc/knowledge-git/bin/program/exception(+0x124e)[0x55555555524e]
Breakpoint 1, 0x00007ffff7e7c750 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) c
Continuing.
Division by zero condition!
[Inferior 1 (process 177) exited normally]
本文暂时没有评论,来添加一个吧(●'◡'●)