• muduo网络库源码学习————Exception类


    Exception类是为异常捕获而设计,可以获得异常的信息以及栈的回溯信息
    (原来的代码没有demangle成员函数,输出的格式比较难看,加了demangle成员函数,利用demangle成员函数可以转换格式,使得输出的格式更加接近我们的习惯)
    以下的代码是加入了demangle成员函数后的:
    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();//构造函数直接调用 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];//保存200个地址,是一个数组的指针
      //栈回溯,保存各个栈帧的地址
      //buffer中的每一个项都是void*,用于保存函数的地址
      int nptrs = ::backtrace(buffer, len);//nptr为实际保存的个数
      //根据地址,转成相应的函数符号
      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_字符串
          stack_.append(demangle(strings[i]));//转化后在存入
          stack_.push_back('
    ');
        }
        free(strings);//存放的地址使用malloc开辟出来的,需要我们自己释放
      }
    }
    //该函数实现栈回溯信息的格式转换
    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类测试函数
    #include <muduo/base/Exception.h>
    #include <stdio.h>
    //定义Bar类
    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
    ", ex.what());//抛出异常信息
        printf("stack trace: %s
    ", ex.stackTrace());//把异常栈回溯信息抛出,即在哪里抛出异常,打印函数的调用栈
      }
    }
    

    单独编译后运行结果如下:(没有使用demangle成员函数)
    这里写图片描述
    使用demangle成员函数:
    这里写图片描述

  • 相关阅读:
    HBase 高性能加入数据
    Please do not register multiple Pages in undefined.js 小程序报错的几种解决方案
    小程序跳转时传多个参数及获取
    vue项目 调用百度地图 BMap is not defined
    vue生命周期小笔记
    解决小程序背景图片在真机上不能查看的问题
    vue项目 菜单侧边栏随着右侧内容盒子的高度实时变化
    vue项目 一行js代码搞定点击图片放大缩小
    微信小程序进行地图导航使用地图功能
    小程序报错Do not have xx handler in current page的解决方法
  • 原文地址:https://www.cnblogs.com/sigma0-/p/12630488.html
Copyright © 2020-2023  润新知