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入门 之 zTree(十二 托拽事件(二))
1.逻辑可能有不完善的地方,如果发现,请指出. <!DOCTYPE html> <HTML> <HEAD> <TITLE> ZTREE DEMO - d ...
- 10-jmeter 测试soap协议v1.2版本请求
1.因为jmeter安装了第三方插件jmeter-plugins-manager.jar之后(具体安装看之前文章),此时就可简单直接测试soap协议1.2版本的请求了 2. 3.进行运行线程就可实现了 ...
- tf.nn.dropout 激活函数
tf.nn.dropout(x,keep_prob,noise_shape=None,seed=None,name=None) 参数: x:一个浮点型Tensor. keep_prob:一个标量Ten ...
- vue 全局自定义组件
1.vue文件 <template> <div style="position: absolute;bottom: 10px;text-align: center;widt ...
- AJ学IOS(41)UI之核心动画 两行代码搞定3D转场
AJ分享,必须精品 效果: 代码: 其实代码很少,苹果都给封装好了 // 1.创建核心动画 CATransition *ca = [CATransition animation]; // 1.1动画过 ...
- python实现双向链表的操作
双向链表 双向链表又叫做双链表,每个节点有两个指针域和一个数据域.prev指针域指向前一个节点,next指针域指向下一个节点.注意,第一个节点的prev指针域指向空值,最后一个节点的next域也是指向 ...
- 批量重命名脚本(Python)
便携的批处理脚本,代码如下: import os import sys def rename(): path=input("请输入路径(例如D:/picture):") name= ...
- secureCRT常用操作
直接在网上搜索下载 连接 选择协议 Telnet Telnet连接时,进入输入密码 串口 连接串口后,查看本机连接的串口号 新建的时候,选择相同的串口号 RTS需要勾选掉 外观字体 选项 => ...
- testNG 断言
testNG提供一个Assert类,来判断输出值是否与预期值一致,Assert常用的方法有: Assert.assertEquals():此方法可以有两个参数值,也可以有3个参数值,参数的顺序是 ac ...
- mysql 更改默认字符集
mysql 默认字符集概述 首先,MySQL的字符集问题主要是两个概念: haracter Sets Collations 前者是字符内容及编码,后者是对前者进行比较操作的一些规则.这两个参数集可以在 ...