Exception 类图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
-message_: string
-stack_:string
<<create>>-Exception(what:
char
)
<<create>>-Exception(what:string)
<<destroy>>-Exception()
+what():
const
char
*
+stackTrace():
const
char
*
-fillStackTrace ():
void
|
下面是源代码:
头文件:
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
|
#ifndef MUDUO_BASE_EXCEPTION_H
#define MUDUO_BASE_EXCEPTION_H
#include <muduo/base/Types.h>
#include <exception>
namespace
muduo
{
class
Exception :
public
std::exception
{
public
:
explicit
Exception(
const
char
* what);
explicit
Exception(
const
string& what);
virtual
~Exception()
throw
();
virtual
const
char
* what()
const
throw
();
const
char
* stackTrace()
const
throw
();
private
:
void
fillStackTrace();
string message_;
string stack_;
};
}
#endif // MUDUO_BASE_EXCEPTION_
|
源文件
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
76
77
78
79
80
81
82
83
|
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)
#include <muduo/base/Exception.h>
//#include <cxxabi.h>
#include <execinfo.h>
#include <stdlib.h>
using
namespace
muduo;
Exception::Exception(
const
char
* msg)
: message_(msg)
{
fillStackTrace();
}
Exception::Exception(
const
string& msg)
: message_(msg)
{
fillStackTrace();
}
Exception::~Exception()
throw
()
{
}
const
char
* Exception::what()
const
throw
()
{
return
message_.c_str();
}
const
char
* Exception::stackTrace()
const
throw
()
{
return
stack_.c_str();
}
//填充错误堆栈
void
Exception::fillStackTrace()
{
const
int
len = 200;
void
* buffer[len];
/*
backtrace() returns a backtrace for the calling program, in the array pointed to by buffer. A backtrace is the series of currently
active function calls for the program. Each item in the array pointed to by buffer is of type void *, and is the return address from
the corresponding stack frame. The size argument specifies the maximum number of addresses that can be stored in buffer.
*/
//buffer 存地就是函数的地址
int
nptrs = ::backtrace(buffer, len);
/*
Given the set of addresses returned by backtrace() in buffer, backtrace_symbols() translates the addresses into an array of strings
that describe the addresses symbolically. The size argument specifies the number of addresses in buffer. The symbolic representation
of each address consists of the function name (if this can be determined), a hexadecimal offset into the function, and the actual
return address (in hexadecimal). The address of the array of string pointers is returned as the function result of backtrace_sym-
bols(). This array is malloc(3)ed by backtrace_symbols(), and must be freed by the caller. (The strings pointed to by the array of
pointers need not and should not be freed.)
Pointer--------pointer1 ------string
--------------pointer2 ------string
--------------pointer3 ------string
--------------pointer4 ------string
--------------pointer5 ------string
--------------pointer6 ------string
我们要释放pointer占用的内存,但是pointer所指向的内存不需要我们释放
free (Pointer) 就OK了
*/
//将buffer里面的地址转换为函数符号,也可以所说函数的名字
char
** strings = ::backtrace_symbols(buffer, nptrs);
if
(strings)
{
for
(
int
i = 0; i < nptrs; ++i)
{
// TODO demangle funcion name with abi::__cxa_demangle
stack_.append(strings[i]);
stack_.push_back(
'\n'
);
}
//这个要自己释放
free
(strings);
}
}
|
测试程序
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
|
#include <muduo/base/Exception.h>
#include <stdio.h>
class
Bar
{
public
:
void
test()
{
throw
muduo::Exception(
"oops"
);
}
};
void
foo()
{
Bar b;
b.test();
}
int
main()
{
try
{
foo();
}
catch
(
const
muduo::Exception& ex)
{
printf
(
"reason: %s\n"
, ex.what());
printf
(
"stack trace: %s\n"
, ex.stackTrace());
}
}
|
程序输出:
1
2
3
4
5
6
7
8
|
reason: oops
stack trace: muduo::Exception::fillStackTrace()
muduo::Exception::Exception(
char
const
*)
Bar::test()
foo()
./exception_test(main+0x10)
/lib/libc.so.6(__libc_start_main+0xe6)
./exception_test()
|