#include <execinfo.h>
int backtrace(void** buffer,int size);
buffer:是一個指針數組,數組中存放的是調用過的函數地址
buffer-----> ---------------
| 調用函數地址 |
---------------
| |
---------------
| |
---------------
返回值:數組中存放的元素的個數
char** backtrace_symbols(void* const *buffer,int size);
將調用的函數地址轉換成字符串
返回值:指針數組,數組中的元素是函數地址對應的字符串(編譯期已確定)
注意:這裏的數組是由malloc分配出來的,所以我們需要手動釋放該數組內存,而數組中指向的字符串有系統釋放。
重要函數:fillStackTrace()
void Exception::fillStackTrace()
{
const int len = 200;
void* buffer[len];
int nptrs = ::backtrace(buffer, len);
char** strings = ::backtrace_symbols(buffer, nptrs);
if (strings)
{
for (int i = 0; i < nptrs; ++i)
{
stack_.append(strings[i]);
stack_.push_back('\n');
}
free(strings);
}
}
- 異常類定義(其他成員函數沒什麼難點)
explicit :修飾的構造函數只能顯示初始化
成員函數加throw():該函數不拋出異常
class Exception : public std::exception
{
public:
explicit Exception(const char* what):message_(what)
{
fillStackTrace();
}
explicit Exception(const string& what)
:message_(what)
{
fillStackTrace();
}
virtual ~Exception() throw(){};
virtual const char* what() const throw();
const char* stackTrace() const throw()
{
return stack_.c_str();
}
private:
void fillStackTrace();
string message_;
string stack_;
};
const char* Exception::what() const throw()
{
return message_.c_str();
}