zoukankan      html  css  js  c++  java
  • 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成员函数:
    这里写图片描述

  • 相关阅读:
    deepin 安装版本管理工具
    deepin 安装maven
    deepin 安装 idea
    启动VMware环境下的Linux操作系统,添加新分区
    Centos6.*安装vsftpd
    easyui-datebox 年月视图显示
    oracle-数据库泵EXPDP导出用户下所有
    Oracle虚拟机配置
    JSON理解
    Python语法基础_04.元组、函数-上
  • 原文地址:https://www.cnblogs.com/sigma0-/p/12630488.html
Copyright © 2011-2022 走看看