12muduo_base库源码分析(三)

来源:互联网 发布:数据分析工程师 外企 编辑:程序博客网 时间:2024/06/02 00:19

1.Exception类实现

   (1)backtrace,栈回溯,保存各个栈帧的地址 
  (2)backtrace_symbols,根据地址,转成相应的函数符号
  (3)abi::__cxa_demangle

2.代码

Exception.h

// 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)#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 demangle(const char* symbol);  string message_;  string stack_;};}#endif  // MUDUO_BASE_EXCEPTION_H

Exception.cc

// 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>#include <stdio.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)    {      // TODO demangle funcion name with abi::__cxa_demangle      //stack_.append(strings[i]);  stack_.append(demangle(strings[i]));      stack_.push_back('\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;}

Exception_test.cpp


#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());  }}

执行结果


原创粉丝点击