Exception::what() 返回出错信息
Exception::stackTrace() 返回出错时的调用栈
实现:
#include <exception>
backtrace,栈回溯,保存各个栈帧的地址
backtrace_symbols,根据地址,转成相应的函数符号
#include <cxxabi.h>
abi::__cxa_demangle :将编译修改过后的函数符号转化为原始代码中的函数符合
头文件 Exception.h
#ifndef MUDUO_BASE_EXCEPTION_H
#define MUDUO_BASE_EXCEPTION_H
#include <muduo/base/Types.h>
#include <exception>
#include <stdio.h>
#include <cxxabi.h> //demangle
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 demangle(const char* symbol);
string message_;
string stack_;
};
}
#endif
Exception.cc
#include <muduo/base/Exception.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];
int nptrs = backtrace(buffer,len);
char** strings=::backtrace_symbols(buffer,nptrs);
if(strings)
{
for(int i=0;i<nptrs;++i)
{
stack_.append(demangle(strings[i]));
stack_.append("\n");
}
free(strings);
}
}
string Exception::demangle(const char* symbol)
{
size_t size;
int status;
char temp[128];
char* demangled;
//first, try to demangle a c++ name
if (1 == sscanf(symbol, "%*[^(]%*[^_]%127[^)+]", temp)) {
if (NULL != (demangled = abi::__cxa_demangle(temp, NULL, &size, &status))) {
string result(demangled);
free(demangled);
return result;
}
}
//if that didn't work, try to get a regular c symbol
if (1 == sscanf(symbol, "%127s", temp)) {
return temp;
}
//if all else fails, just return the symbol
return symbol;
}
参考:c++教程网