muduo源码学习base——Exception(带 stack trace 的异常基类)

news2025/1/12 20:41:19

Exception(带 stack trace 的异常基类)

  • 前置
  • Exception
    • CurrentThread::stackTrace()

前置

ABI:

  • Application Binary Interface,应用程序二进制接口,可以参考:细谈ABI

RTTI type_info:

  • RTTI:Run Time Type Identification,运行时类型识别

mangle 和 demangle

  • mangle: c++为了实现重载和重写等,对符号进行了mangling,见文章:重载的函数名部分 例如func变为_Z4funcidPi
  • demangle:还原被mangled的名字

statcktrace:

  • 栈回溯,系统自主打印进程调用栈的行为

backtrace: ———— 参考:backtrace函数

  • 标准库中有三个函数包含在头文件<execinfo.h>下:
    1.int backtrace(void **buffer, int size);
    该函数获取当前线程的调用堆栈,获取的信息将会被存放在buffer中,它是一个指针数组,参数size用来指定buffer中可以保存多少个void元素 函数的返回值是实际返回的void元素个数 buffer中的void*元素实际是从堆栈中获取的返回地址
    2.char **backtrace_symbols(void *const *buffer, int size);
    该函数将backtrace函数获取的信息转化为一个字符串数组,参数buffer是backtrace获取的堆栈指针,size是backtrace返回值。函数返回值是一个指向字符串数组的指针,它包含char*元素个数为size 每个字符串包含了一个相对于buffer中对应元素的可打印信息,包括函数名、函数偏移地址和实际返回地址(backtrace_symbols生成的字符串占用的内存是malloc出来的,但是是一次性malloc出来的,释放是只需要一次性释放返回的二级指针即可)
    返回值大概是这样的: ./testexception() [0x40144f] /lib64/libc.so.6(__libc_start_main+0xf3) [0x7f5c17b90493] ./testexception() [0x4012be]
    在这里插入图片描述
    编译时加上–rdynamic选项可以打印出括号里的函数名称
    在这里插入图片描述
    3.void backtrace_symbols_fd(void *const *buffer, int size, int fd);
    该函数与backtrace_symbols函数功能相同,只是它不会malloc内存,而是将结果写入文件描述符为fd的文件中,每个函数对应一行 该函数可重入

abi::__cxa_demangle:
char* abi::__cxa_demangle (const char* mangled_name, char* output_buffer, size_t* length, int* status)
mangled_name

  • 顾名思义

output_buffer

  • 内存区域,使用 malloc 分配,*length 字节,其中存储了 demangled 名称。 如果 output_buffer 不够长,则使用 realloc 对其进行扩展。 output_buffer 可以改为 NULL; 在这种情况下,demangled 名称被放置在用 malloc 分配的内存区域中

length:

  • 在output_biffer中demangled的名称个数

status:

  • 0:操作成功
  • -1内存分配错误
  • -2非有效mangle_name
  • -3有传入的参数无效

返回值:成功返回以NULL结尾的指向demangle_name的字符数组指针,失败返回NULL,注意:调用者应负责次此处的free()

Exception

最新C++11版muduo将fillStackTrace()和自定义demangle函数整合到了CurrentThread::stackTrace函数中
类图:
在这里插入图片描述

  • what():打印一条自定义消息
  • stackTrace():返回stack_.c_str()
  • 在构造函数,调用CurrentThread::stackTrace,进行demangle,填充字符串stack

CurrentThread::stackTrace()

string stackTrace(bool demangle)//是否需要进行demangle
{
 string stack;
 const int max_frames = 200;//最多有200个栈地址
 void* frame[max_frames];//void **指针数组
 int nptrs = ::backtrace(frame, max_frames);//栈地址个数
 char** strings = ::backtrace_symbols(frame, nptrs);
 //strings是一个指向字符串数组的指针,它包含char*元素个数为nptrs 每个字符串包含了一个相对于frame中对应元素的可打印信息
 //通常是这样: ./testexception(main+0xc2) [0x401a5f] /lib64/libc.so.6(__libc_start_main+0xf3) [0x7f49991cf493]
 if (strings)
 {
   size_t len = 256;
   char* demangled = demangle ? static_cast<char*>(::malloc(len)) : nullptr;//用来存储demangle后的函数名
   for (int i = 1; i < nptrs; ++i)  //跳过0(0是当前函数)
   {
     if (demangle)//如果需要进行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';截取'(''+'部分的mangled_name
         int status = 0;
         char* ret = abi::__cxa_demangle(left_par+1, demangled, &len, &status);//进行demangle
         *plus = '+';//还原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);//一次性释放backtrace_symbols返回的二级指针
 }
 return stack;
}

逻辑就是将demangle和fillstacktrace整合到一起,见注释,分别从strings中取出来,一一demangle


下面是测试用例Exception_test.cc的运行结果:

  • Stack:在这里插入图片描述
  • Stack inside lambda:
    在这里插入图片描述
  • Stack inside std::function:
    在这里插入图片描述
  • Stack inside std::bind:
    在这里插入图片描述
  • 原stack trace:
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1127852.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

js给一段话,遇到的第一个括号处加上换行符

list.forEach((item,index0)>{const productName item.name;const index productName.indexOf(&#xff08;);if (index -1) {return productName;}const before productName.slice(0, index);const after productName.slice(index);item.namebefore \n after;});

算法学习(七)判断一个二叉树是否为完全二叉树

描述 给定一个二叉树&#xff0c;确定他是否是一个完全二叉树。 完全二叉树的定义&#xff1a;若二叉树的深度为 h&#xff0c;除第 h 层外&#xff0c;其它各层的结点数都达到最大个数&#xff0c;第 h 层所有的叶子结点都连续集中在最左边&#xff0c;这就是完全二叉树。&a…

值改变事件(SMART PLC梯形图FC)

值改变事件在通信速度优化上的应用,请查看下面文章链接: C#winform事件驱动 值改变事件 PLC寄存器值改变_plc数据变化触发条件_RXXW_Dor的博客-CSDN博客Modbus通讯时,设置值发生改变时,我们希望启动一次请求帧,发送写数据帧,这个功能,在C#winform里很容易实现,因为有对…

“唯品会VIP商品搜索API:尊享购物体验,一键获取心仪商品!“

唯品会按关键字搜索VIP商品API是一项面向唯品会VIP用户的API服务&#xff0c;它主要用于在唯品会网站上根据用户指定的关键字快速搜索到VIP商品&#xff0c;并提供商品详情、价格、库存量、评价等信息。这个API的核心功能是为用户提供便捷且准确的搜索服务&#xff0c;让用户能…

探索二次开发途径

一、什么是二次开发&#xff1f; 软件二次开发&#xff0c;也被称为定制开发或应用开发&#xff0c;是指在已有的软件基础上&#xff0c;通过编写自定义代码或应用程序来满足特定需求&#xff0c;扩展现有软件的功能。这种方式可在满足定制需求的同时&#xff0c;减少了开发新…

【会议征稿通知】第二届语言与文化传播国际学术会议(ICLCC 2024)

第二届语言与文化传播国际学术会议&#xff08;ICLCC 2024&#xff09; The 2nd International Conference on Language and Cultural Communication 第二届语言与文化传播国际学术会议&#xff08;ICLCC 2024&#xff09;的目标是将语言与文化传播领域的创新学者和行业专家聚…

利用ChatGPT自动生成基于PO的数据驱动测试框架

简介 PO&#xff08;PageObject&#xff09;设计模式将某个页面的所有元素对象定位和对元素对象的操作封装成一个 Page 类&#xff0c;并以页面为单位来写测试用例&#xff0c;实现页面对象和测试用例的分离。 数据驱动测试&#xff08;DDT&#xff09;是一种方法&#xff0c…

有奖招募——2023年度清华社“荐书官”活动今日开始了!

又到“1024程序员节”了&#xff0c;维护网络世界稳定和平的程序员大大们&#xff0c;辛苦了&#xff01;生活难免有bug&#xff0c;来给彼此个hug~ 过完1024&#xff0c;这一年也快要结束了&#xff0c;岁末回顾又要提上日程。很多人都有整理年度书单的习惯&#xff0c;那么这…

服务器数据恢复-服务器系统损坏启动蓝屏的数据恢复案例

服务器故障&分析&#xff1a; 某公司一台华为机架式服务器&#xff0c;运行过程中突然蓝屏。管理员将服务器进行了重启&#xff0c;但是服务器操作系统仍然进入蓝屏状态。 导致服务器蓝屏的原因非常多&#xff0c;比较常见的有&#xff1a;显卡/内存/cpu或者其他板卡接触不…

基于SSM的流浪动物领养信息系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

lua-web-utils和proxy程序示例

以下是一个使用lua-web-utils和https://www.duoip.cn/get_proxy的爬虫程序示例。每行代码后面都给出了详细的中文解释。 -- 导入所需的库 local http require("http") local ltn12 require("ltn12") local json require("json") local web_u…

GitLab升级16.5.0后访问提示502

系统是兼容CentOS8的TencentOS3.1 GitLab原来的版本是16.4.1 使用yum升级时发现GitLab有新版本,决定升级。 升级过程无异常,出现升级成功的提示。 可是意外的时,访问站点时提示502. GitLab比较吃资源,启动的服务较多。之前也有等会就正常的情况。 这次没那么幸运,一…

python爬虫-某政府网站反爬小记——请求参数base64加密

注意&#xff01;&#xff01;&#xff01;&#xff01;某XX网站逆向实例仅作为学习案例&#xff0c;禁止其他个人以及团体做谋利用途&#xff01;&#xff01;&#xff01; 第一步&#xff0c;正常分析页面&#xff0c;可以看到请求参数被加密了 第二步&#xff0c; 打断点查…

imu的静止零偏噪声标定与积分

示例使用的Imu为轮趣科技 n100 mini其中imu出来的数据的坐标系是基于ROS坐标系的 Eigen::Quaterniond q_ahrs(ahrs_frame_.frame.data.data_pack.Qw,ahrs_frame_.frame.data.data_pack.Qx,ahrs_frame_.frame.data.data_pack.Qy,ahrs_frame_.frame.data.data_pack.Qz);Eigen::…

Android Kotlin 协程初探 | 京东物流技术团队

1 它是什么&#xff08;协程 和 Kotlin协程&#xff09; 1.1 协程是什么 维基百科&#xff1a;协程&#xff0c;英文Coroutine [kəru’tin] &#xff08;可入厅&#xff09;&#xff0c;是计算机程序的一类组件&#xff0c;推广了协作式多任务的子程序&#xff0c;允许执行被…

QSPI介绍

0 Preface/Foreword 1 QSPI介绍

数据结构与算法课后题-第七章(顺序查找和折半查找)

牛刀小试&#xff0c;做一下小题&#xff0c;检查一下自己的基础知识掌握的情况。 文章目录 牛刀小试1牛刀小试2牛刀小试3牛刀小试4牛刀小试5牛刀小试6牛刀小试7牛刀小试8牛刀小试9牛刀小试10牛刀小试11牛刀小试12牛刀小试13牛刀小试14牛刀小试15 牛刀小试1 牛刀小试2 错题分析…

从「纯野妆」到「降温妆」,解析小红书“热词爆款学”

白开水妆、视觉降温妆、亚裔辣妹妆......打开小红书的美妆板块&#xff0c;你会发现许多这类极具创意的妆容热词。小红书用户乐于尝鲜、乐于创新&#xff0c;具有强大的创造能力&#xff0c;热衷于为产品、为妆容、为穿搭起“外号”。这些“外号”往往能突破原有思维的束缚&…

el-select multiple表单校验问题

el-select multiple表单校验问题 <el-form refform :modelform><el-form-item propvulTypes label漏洞类型><el-select v-modelform.vulTypes changevulTypeChange><el-option v-foritem in vulList :keyitem :labelitem :valueitem></el-option&g…

智能井盖传感器特点是什么?

在城市基础设施建设过程中&#xff0c;无论是国际大都市还是小县城&#xff0c;井盖所导致的问题会严重影响着城市地下生命线。井盖如若出现移动翻转等现象&#xff0c;是市民生命安全的潜在隐患&#xff0c;也有可能会影响下水道&#xff0c;供水管道等正常运行。所以传统井盖…