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('\n');
}
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\n", ex.what());//抛出异常信息
printf("stack trace: %s\n", ex.stackTrace());//把异常栈回溯信息抛出,即在哪里抛出异常,打印函数的调用栈
}
}
单独编译后运行结果如下:(没有使用demangle成员函数)
使用demangle成员函数:
muduo网络库源码学习————Exception类的更多相关文章
- muduo网络库源码学习————线程类
muduo库里面的线程类是使用基于对象的编程思想,源码目录为muduo/base,如下所示: 线程类头文件: // Use of this source code is governed by a B ...
- muduo网络库源码学习————日志类封装
muduo库里面的日志使方法如下 这里定义了一个宏 #define LOG_INFO if (muduo::Logger::logLevel() <= muduo::Logger::INFO) ...
- muduo网络库源码学习————Timestamp.cc
今天开始学习陈硕先生的muduo网络库,moduo网络库得到很多好评,陈硕先生自己也说核心代码不超过5000行,所以我觉得有必要拿过来好好学习下,学习的时候在源码上面添加一些自己的注释,方便日后理解, ...
- muduo网络库源码学习————线程池实现
muduo库里面的线程池是固定线程池,即创建的线程池里面的线程个数是一定的,不是动态的.线程池里面一般要包含线程队列还有任务队列,外部程序将任务存放到线程池的任务队列中,线程池中的线程队列执行任务,也 ...
- muduo网络库源码学习————互斥锁
muduo源码的互斥锁源码位于muduo/base,Mutex.h,进行了两个类的封装,在实际的使用中更常使用MutexLockGuard类,因为该类可以在析构函数中自动解锁,避免了某些情况忘记解锁. ...
- muduo网络库源码学习————线程本地单例类封装
muduo库中线程本地单例类封装代码是ThreadLocalSingleton.h 如下所示: //线程本地单例类封装 // Use of this source code is governed b ...
- muduo网络库源码学习————日志滚动
muduo库里面的实现日志滚动有两种条件,一种是日志文件大小达到预设值,另一种是时间到达超过当天.滚动日志类的文件是LogFile.cc ,LogFile.h 代码如下: LogFile.cc #in ...
- muduo网络库源码学习————线程特定数据
muduo库线程特定数据源码文件为ThreadLocal.h //线程本地存储 // Use of this source code is governed by a BSD-style licens ...
- muduo网络库源码学习————无界队列和有界队列
muduo库里实现了两个队列模板类:无界队列为BlockingQueue.h,有界队列为BoundedBlockingQueue.h,两个测试程序实现了生产者和消费者模型.(这里以无界队列为例,有界队 ...
随机推荐
- javascript 入门 之select2获取远程数据
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <meta lan ...
- "首字母变大写"组件:<capitalize> —— 快应用组件库H-UI
 <import name="capitalize" src="../Common/ui/h-ui/text/c_text_capitalize"> ...
- 彻底卸载----LoadRunner
保证所有LoadRunner的相关进程(包括Controller.VuGen.Analysis和Agent Process)全部关闭: 备份好LoadRunner安装目录下测试脚本,这些脚本一般存放在 ...
- 【Selenium03篇】python+selenium实现Web自动化:元素三类等待,多窗口切换,警告框处理,下拉框选择
一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 这是python+selenium实现Web自动化第三篇博 ...
- public、private、protected继承区别
- Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十二)之Error Handling with Exceptions
The ideal time to catch an error is at compile time, before you even try to run the program. However ...
- Mac 下 brew 切换为国内源
简介 Homebrew 是一款自由及开放源代码的软件包管理系统,用以简化 macOS 和 linux 系统上的软件安装过程.它拥有安装.卸载.更新.查看.搜索等很多实用的功能,通过简单的一条指令,就可 ...
- 时间格式的转化 vue与js 年月日 时分秒
首先使用原生转化的方法 第一种 //时间转换 dateStr(d, sign) { //如果没有传递符号,给一个默认的符号 if (!sign) { sign = '-' } //获取d里面年月日时分 ...
- L0 torch 构建网络初步
L0 pytorch 构建简单网络 本文是L0, 目的是把pytorch构建感知器的程序,仔细剖析理解. import torch from torch import nn torch.__versi ...
- H - Knight Moves DFS
A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the sh ...