软件测试之SDK开发(ios)——Cpp Exception捕获

2023-05-16

ios虽然是用OC语言或Swift语言进行编程,但是它同时也支持c++语法,底层的动态库也基本上都是C++编写的。所以ios在运行的时候,可能会抛出C++异常,如果该C++异常可以被转换为NSException,就抛给OC异常的捕获机制。如果不能被转换,就继续C++的terminate流程,也就是default_terminate_handler。这个C++异常的默认terminate函数内部调用abort_message函数,最后触发了一个abort调用,系统产生一个SIGABRT信号。

通常情况下,在系统抛出C++异常后,如果被try/catch掉,再重新抛出的C++异常(因为要判断该C++异常是否可以被转换为NSException),异常的现场堆栈已经消失,所以上层通过捕获SIGABRT信号是无法还原发生异常时的场景,即通常我们说的异常堆栈缺失

为什么再重新抛出的C++异常的堆栈会消失,这个主要是因为try/cach语句内部会调用__cxa_rethrow()抛出异常,__cxa_rethrow()内部又会调用 unwindunwind可以简单理解为函数调用的逆调用,主要用来清理函数调用过程中每个函数生成的局部变量,一直到最外层的catch语句所在的函数,并把控制移交给catch语句,这就是C++异常的堆栈消失原因。

整个C++异常的触发和调用流程如下图所示:
在这里插入图片描述
可以使用std::set_terminate();设置崩溃回调,回调代码如下:

static void CPPExceptionTerminate(void){
    NSLog(@"Trapped c++ exception");
    const char* name = NULL;
    std::type_info* tinfo = __cxxabiv1::__cxa_current_exception_type();
    if(tinfo != NULL){
        name = tinfo->name();
    }
    if(name == NULL || strcmp(name, "NSException") != 0){
        
        char descriptionBuff[DESCRIPTION_BUFFER_LENGTH];
        const char* description = descriptionBuff;
        descriptionBuff[0] = 0;
        
        NSLog(@"Discovering what kind of exception was thrown.");
        
        captureStackTrace = false;
        
        try
        {
            throw;
        }
        catch(std::exception& exc)
        {
            strncpy(descriptionBuff, exc.what(), sizeof(descriptionBuff));
        }
#define CATCH_VALUE(TYPE, PRINTFTYPE) \
catch(TYPE value)\
{ \
snprintf(descriptionBuff, sizeof(descriptionBuff), "%" #PRINTFTYPE, value); \
}
        CATCH_VALUE(char,                 d)
        CATCH_VALUE(short,                d)
        CATCH_VALUE(int,                  d)
        CATCH_VALUE(long,                ld)
        CATCH_VALUE(long long,          lld)
        CATCH_VALUE(unsigned char,        u)
        CATCH_VALUE(unsigned short,       u)
        CATCH_VALUE(unsigned int,         u)
        CATCH_VALUE(unsigned long,       lu)
        CATCH_VALUE(unsigned long long, llu)
        CATCH_VALUE(float,                f)
        CATCH_VALUE(double,               f)
        CATCH_VALUE(long double,         Lf)
        CATCH_VALUE(char*,                s)
        catch(...)
        {
            description = NULL;
        }
        captureStackTrace = true;
        
        NSString * callStackSymbols = [BSBacktraceLogger bs_backtrace:backtraceBuffer backtraceLength:backtraceLength] ;
        
        NSString *date = [LLTool stringFromDate:[NSDate date]];
        NSArray *appInfos = [LLRoute appInfos];
        LLCrashModel *model = [[LLCrashModel alloc] initWithName:@"CPP Exception" reason:[NSString stringWithFormat:@"抛出异常:%@",description?[NSString stringWithUTF8String:description]:@"Unknown"] userInfo:nil stackSymbols:@[callStackSymbols] date:date userIdentity:[LLConfig sharedConfig].userIdentity appInfos:appInfos launchDate:[NSObject LL_launchDate]];
        [LLCrashSignalHelper sharedHelper].crashModel = model;
        [[LLStorageManager sharedManager] saveModel:model complete:^(BOOL result) {
            NSLog(@"Save mach model success");
        } synchronous:YES];
        
    }else{
        NSLog(@"Detected NSException. Letting the current NSException handler deal with it.");
    }
    
    NSLog(@"Calling original terminate handler.");
    
    originalTerminateHandler() ;
}

效果演示

C++异常如果通过signal机制进行捕获,会出现异常堆栈缺失问题。测试代码如下:

-(void)testCPPException{
   char* name= "测试Cpp Exception" ;
   throw name;
}

在这里插入图片描述
已经成功捕获了CPP Exception,该功能已经集成到了我开发的SDK里面,效果如下图所示:
在这里插入图片描述
通过CPP Exception的捕获成功将异常的堆栈进行还原,进入到Signal(SIGABRT),可以发现通过signal机制捕获的堆栈出现了异常堆栈缺失问题。如下图所示:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

软件测试之SDK开发(ios)——Cpp Exception捕获 的相关文章

  • iOS 防止计时器 UILabel 在数字变化时“晃动”

    我有一个UILabel它以以下格式显示计时器的输出MM ss SS 分 秒 厘秒 但是随着厘秒宽度的变化 它从左向右 摇动 例如 11 比 33 窄 有什么办法可以减轻这种情况吗 我尝试过将其居中 给它固定的宽度 但它们似乎没有帮助 从iO
  • 为什么密码错误会导致“填充无效且无法删除”?

    我需要一些简单的字符串加密 所以我编写了以下代码 有很多 灵感 来自here http www codeproject com KB security DotNetCrypto aspx create and initialize a cr
  • iOS 视图控制器内存在被关闭后未释放

    当用户单击按钮时 它会显示一个带有两个视图控制器的新选项卡栏视图控制器 我是这样做的 ACLevelDownloadController dvc ACLevelDownloadController alloc initWithNibName
  • 在 HTML5 iOS 7 / iOS 8 中显示十进制键盘

    经过几个小时的搜索后 我只是有一个简单的问题 是否有可能在网络浏览器输入字段中显示小数键盘 input type number 只显示数字 但我需要在左下角使用逗号或点 我尝试过任何事情 pattern step等等 但没有显示十进制键盘
  • 如何解决 CoreData mogenerator 未找到问题

    我收到如下所示的错误 我不知道我错过了什么 我该如何解决这个问题 如下图所示 Users nischalhada Documents XcodePro mnepalnews revisited 2 0 CoreData mogenerato
  • 使用 Interface Builder 创建 UIScrollView 的步骤

    我正在尝试使用 UIScrollView 但似乎有一些基本的事情我不理解 假设我想在我的 iPhone 应用程序中使用 UIScrollView 我有一个充满按钮的视图 尺寸为 320x700 显然 这对于 320x480 的 iPhone
  • 错误:更改核心数据模型后架构armv7的重复符号

    我有一个使用核心数据框架的应用程序 我工作得很好 我刚刚更改了数据模型 向一个实体添加一个属性 当我尝试构建它时 出现错误 duplicate symbol OBJC METACLASS AccountFolder in Users XXX
  • 个人帐户开发者之间的 Apple 开发/分发证书

    我一直在到处寻找有关处理证书的正确答案 想象一下以下帐户 Joe拥有个人 Apple 帐户 但他根本不会编码 他只是发布了该应用程序并将其称为自己的 Bob还有一个个人 Apple 帐户 Bob 是一位编码专家 Joe 付费让他开发他的第一
  • 频繁绘制 CGPath 时的性能

    我正在开发一个将数据可视化为折线图的 iOS 应用程序 该图被绘制为CGPath在全屏自定义中UIView最多包含 320 个数据点 数据经常更新 图表需要相应地重新绘制 刷新率为 10 秒就很好了 到目前为止很容易 然而 我的方法似乎需要
  • 防止 AlertView 被解雇

    任何人都可以帮助我防止在其按钮单击事件上解雇警报视图吗 我有一个 textview 作为我的alertView 的子视图 如果 textview 值为 nil 我不想关闭它 因为这是一个非常老的问题 但我得到了一个解决方案 并且如果其他开发
  • iOS 循环对象的属性并添加操作

    我有一个具有几个类似属性的类 UISliders 我想添加用户开始和结束使用每个滑块时的操作 每个滑块都将链接到同一个选择器 因此我考虑只是迭代它们 而不是编写 10 个几乎相同的代码块 问题是 最有效的方法是什么 我尝试过这样的事情 在运
  • NVActivityIndi​​catorView 仅适用于特定视图

    我正在使用这个库https github com ninjaprox NVActivityIndi catorView https github com ninjaprox NVActivityIndicatorView用于显示加载指示器
  • git 提交错误:检测到大文件

    您好 我正在为 ios 8 1 开发一个应用程序 xcode 我已经使用 googleMaps 框架来实现自动完成功能 当我尝试在 Git 中推送我的项目时 我收到大文件检测错误 后来尝试使用 git lfs 并跟踪 git 检测到的文件
  • 避免 UIImage 的 imageNamed - 内存管理

    我正在经历这个链接 http akosma com 2009 01 28 10 iphone memory management tips 我遇到了一个点避免 UIImage 的 imageNamed 出于什么原因我们应该避免这种情况 它会
  • UIWebView Bug:-[UIWebView cut:]:无法识别的选择器发送到实例

    In the UIWebView 如果包含文本的输入元素具有焦点 并且按下按钮导致输入失去焦点 则随后双击输入以重新获得焦点并从出现的弹出栏中选择 剪切 或 复制 或 粘贴 会导致这UIWebView因错误而崩溃 UIWebView cut
  • 如何反转 CGPath 的点顺序

    我想画一个圆圈 并用它打出字母 为此 我需要顺时针抚摸圆圈 逆时针抚摸字母 这一切都很好 但是当我使用 Core Text 获取字母路径时 我不知道如何从本质上反转该路径 不是镜像或旋转或任何东西 这很简单 我希望点笔画顺序是逆时针的 这实
  • Swift C 回调 - Swift 类指针的 takeUnretainedValue 或 takeRetainedValue

    我有一些UIView or UITableViewCell 里面我有 C 回调 例如 CCallback bridge self observer data gt Void in let mySelf Unmanaged
  • 分发内部业务 IOS 应用程序

    我遇到了 IOS 应用程序分发的一个令人困惑的部分 因此 我需要简单细分一下我的限制 即仅将我的应用程序分发给我的员工 同事或任何被视为 内部 的人 这是表明我不希望该应用程序出现在应用程序商店中的另一种方式 我的情况是我为几家公司开发 他
  • 苹果推送通知在生产中不起作用

    我们完全陷入困境 请帮忙 我和我的团队制作了一个 iPhone 应用程序 这是我们第一次在 iOS 上尝试 一切都很好 直到我们提交应用程序并在应用程序商店上可用为止 推送通知服务无法正常工作 我在网上搜索并尝试根据人们的建议仔细检查我们的
  • MongoDB:javascript执行失败:无法在 src/mongo/shell/collection.js 保存 DBQuery 对象

    在 MongoDb 中 当我尝试修改集合中的现有文档时 它会生成以下异常 javascript execution failed can t save a DBQuery object at src mongo shell collecti

随机推荐

  • Java高并发秒杀平台(Redis + RabbitMQ)

    Seconds Kill 本项目是一个模拟高并发环境下基于 SpringBoot 的秒杀购物平台 为了减少对数据库的直接访问 xff0c 通过 Redis 实现了缓存优化 xff1b 并通过 RabbitMQ 消息中间件来接收大量的并发请求
  • Ubuntu 配置

    配置源 如果是网通或者教育网建议选择上海交大的源 sudo cp etc apt sources list etc apt sources list backup sudo gedit etc apt sources list 用以下内容替
  • vncserver: Failed command ‘/etc/X11/Xvnc-session‘: 256!

    安装vncserver启动时出现如下报错 xff1a Starting applications specified span class token keyword in span etc X11 Xvnc session Log spa
  • Windows Media Player SDK 简介

    Windows Media Player SDK 简介 2002年9月 适用于 xff1a Microsoft Windows Media Player 摘要 xff1a 了解如何更改 Windows Media Player 的外观和行为
  • Linux glibc幽灵(GHOST)漏洞检测及修复方案

    安全研究人员近日曝出一个名为幽灵 xff08 GHOST xff09 的严重安全漏洞 xff0c 这个漏洞可以允许攻击者远程获取操作系统的最高控制权限 xff0c 影响市面上大量Linux操作系统及其发行版 该漏洞CVE编号为CVE 201
  • Byte Buddy 入门教程

    为什么需要运行时代码生成 我们知道 xff0c Java 是一种强类型的编程语言 xff0c 即要求所有变量和对象都有一个确定的类型 xff0c 如果在赋值操作中出现类型不兼容的情况 xff0c 就会抛出异常 强类型检查在大多数情况下是可行
  • android graphic(14)—EGL和OpenGL ES之间的关系

    OpenGL ES EGL 例子 EGL加载OpenGL ES库 涉及的库 库的加载 小结 OpenGL ES 什么是OpenGL xff1f Open Graphics Library OpenGL is a cross language
  • 删除多余的Linux图标

    一 空间杀手 使用Docker一段时间后 xff0c 发现C盘剩余空间显著减少 究其原因 xff0c 首先 xff0c 多了Linux子系统 接着 xff0c 看看其占用的空间 xff0c 打开 AppData local 目录下的Dock
  • Web项目停止在Not binding factory to JNDI, no JNDI name configured

    三月 03 2017 9 24 50 下午 org hibernate impl SessionFactoryObjectFactory addInstance 信息 Not binding factory to JNDI no JNDI
  • if-else语句省略{}时不可以定义变量,否则报错

    public void test 带 时可以定义变量和赋值运算等语句 if true int a 61 0 else int b 61 0 不带 时 xff0c 不能定义变量 if true int a 61 0 else int b 61
  • JDK常用API

    本篇介绍Java基础中常用API使用 xff0c 当然只是简单介绍 xff0c 围绕重要知识点引入 xff0c 巩固开发知识 xff0c 深入了解每个API的使用 xff0c 查看Java API文档是必不可少的 一 java lang包下
  • Android butterknife click事件全部失效问题

    问题 xff1a APP突然所有使用butterknife的 64 onClick方式实现的按钮点击事件均失效 解决 xff1a 查看butterknife源代码的DebouncingOnClickListener类 public abst
  • SSH用getHibernateTemplate()更新需要更新的字段

    转 上一篇文章说了hibernate中可以设置dynamic update 来实现跟新某些字段 但是使用了HibernateTemplate xff0c 调用HibernateTemplate saveOrUpdate 方法却还是全部字段更
  • Cannot create PoolableConnectionFactory (Access denied for user 'root'@'localhost' (using password:

    新下载的项目 xff0c 测试时出现Cannot create PoolableConnectionFactory Access denied for user 39 root 39 64 39 localhost 39 using pas
  • 阿里云部署nginx服务器存储图片

    最近想将本地的代码部署到阿里云上 xff0c 1 首先遇到的一个问题就是nginx服务器上传图片连接失败的问题 因为阿里云使用的不是iptables防火墙 xff0c 而是firewalld防火墙 可以在阿里云中选择自己的实例 xff0c
  • windows系统mysql解压版安装教程

    目录 xff1a 1 下载mysql 5 7 18 winx64 zip压缩包 xff1b 2 解压压缩包 xff1b 3 配置mysql环境变量 xff1b 4 新建my ini文件 xff1b 5 安装mydsql xff1b 6 初始
  • 去哪儿2017校园招聘笔试题

    span class hljs keyword import span java util Scanner span class hljs javadoc filename extension 时间限制 xff1a C C 43 43 语言
  • 刷机镜像

    android设备从硬件到系统的结构 xff1a Bootloader是一个叫uboot的程序 xff0c 其支持非常多的体系结构 uboot编译后会生成uboot bin镜像 xff0c 可以作为bootloader使用 Bootload
  • 日志文件xml

    lt xml version 61 34 1 0 34 encoding 61 34 UTF 8 34 gt lt ConsoleAppender 控制台输出日志 gt lt appender name 61 34 STDOUT 34 cl
  • 软件测试之SDK开发(ios)——Cpp Exception捕获

    ios虽然是用OC语言或Swift语言进行编程 xff0c 但是它同时也支持c 43 43 语法 xff0c 底层的动态库也基本上都是C 43 43 编写的 所以ios在运行的时候 xff0c 可能会抛出C 43 43 异常 xff0c 如