muduo源码阅读笔记之异常处理

这篇博客介绍了如何在C++中实现自定义异常类,该类继承自std::exception,提供noexcept和override特性。关键功能在于打印函数调用栈,利用backtrace和backtrace_symbols系统函数获取并解析栈帧信息,包括函数名。文章还详细解释了demangling的过程,以获得可读的函数名称。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

异常

代码位置:base/Exception.h base/Exception.cc
其中noexcept表示当前函数不会产生异常,override表示当前函数是重写了父类的虚函数,异常处理是通过继承std的exception类实现的,其中重写了what和stackTrace函数

class Exception : public std::exception
{
 public:
  Exception(std::string what);
  ~Exception() noexcept override = default;
  // default copy-ctor and operator= are okay.
  const char* what() const noexcept override
  {
    return message_.c_str();
  }
  const char* stackTrace() const noexcept
  {
    return stack_.c_str();
  }
 private:
  std::string message_;
  std::string stack_;
};

其中最主要的功能是打印函数调用栈,该功能的实现主要借助了backtrace和backtrace_symbols两个系统函数
在这里插入图片描述
其中backtrace函数可以获取函数调用的栈帧的地址
而backtrace_symbol可以获取栈帧地址对应的函数名

string stackTrace(bool demangle)
{
  string stack;
  const int max_frames = 200;
  void* frame[max_frames];
  int nptrs = ::backtrace(frame, max_frames);
  char** strings = ::backtrace_symbols(frame, nptrs);
  if (strings)
  {
    size_t len = 256;
    char* demangled = demangle ? static_cast<char*>(::malloc(len)) : nullptr;
    for (int i = 1; i < nptrs; ++i)  // skipping the 0-th, which is this function
    {
      if (demangle)
      {
        // https://panthema.net/2008/0901-stacktrace-demangled/
        // bin/exception_test(_ZN3Bar4testEv+0x79) [0x401909]
        char* left_par = nullptr;
        char* plus = nullptr;
        for (char* p = strings[i]; *p; ++p)
        {
          if (*p == '(')
            left_par = p;
          else if (*p == '+')
            plus = p;
        }
        if (left_par && plus)
        {
          *plus = '\0';
          int status = 0;
          char* ret = abi::__cxa_demangle(left_par+1, demangled, &len, &status);
          *plus = '+';
          if (status == 0)
          {
            demangled = ret;  // ret could be realloc()
            stack.append(strings[i], left_par+1);
            stack.append(demangled);
            stack.append(plus);
            stack.push_back('\n');
            continue;
          }
        }
      }
      // Fallback to mangled names
      stack.append(strings[i]);
      stack.push_back('\n');
    }
    free(demangled);
    free(strings);
  }
  return stack;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值