返回顶部
首页 > 资讯 > 移动开发 >NSMutable 对象的坑解决分析
  • 232
分享到

NSMutable 对象的坑解决分析

NSMutable 对象坑NSMutable 对象 2023-02-28 17:02:18 232人浏览 八月长安
摘要

目录背景测试代码_set +0x10 处是个啥?结论NSMutable 对象共性问题?背景 最近处理了两个崩溃,都是在 NSMutableSet 调用 enumerateO

背景

最近处理了两个崩溃,都是在 NSMutableSet 调用 enumerateObjectsWithOptions 的时候发生的,崩溃类型悬垂指针。 查看崩溃堆栈里面的业务代码,发现 setremoveObjectaddObject 的操作,按照经验来讲这大概率是一个多线程操作 set 造成的。最开始怀疑的是 removeObject 导致遍历的时候访问到了 releaseobj 对象。但是当保证 removeObjectenumerateObjectsWithOptions 在同一个 queue 执行的时候崩溃仍然存在。

测试代码

尝试暴力复现,测试 addObjectenumerateObjectsWithOptions 是否存在多线程访问的问题。

NSMutableSet *_set = [NSMutableSet set];
dispatch_async(dispatch_queue_create("queue", 0x0), ^{
  for (int i = 0; i < 10000; i++) {
    [_set enumerateObjectsUsingBlock:^(id  _Nonnull obj, BOOL * _Nonnull stop) {}];
  }
});
for (int i = 0; i < 10000; i++) {
  [_set addObject:[NSObject new]];
}

复现了崩溃,非法地址访问,崩溃地址 0x14ff1f228

崩溃时的汇编指令和 x22 寄存器相关。

    0x18a6cb260 <+148>: mov    w24, #0x0
    0x18a6cb264 <+152>: adrp   x25, 358888
    0x18a6cb268 <+156>: add    x25, x25, #0xd90          ; ___NSSetM_DeletedMarker
->  0x18a6cb26c <+160>: ldr    x20, [x22, w24, uxtw #3]
    0x18a6cb270 <+164>: cmp    x20, #0x0
    0x18a6cb274 <+168>: ccmp   x20, x25, #0x4, ne

再次执行测试代码,断点到崩溃地址 0x18a6cb26c,此时 x22 的值 0x0000000280567d00

_set 的地址 0x0000000280098560

memory read _set:

x22 这个值在 _set + 0x10 的位置。对 _set + 0x10 处添加内存断点查看修改这个值的逻辑。

(lldb) watchpoint set expression -w write -- 0x0000000282963fd0
Watchpoint created: Watchpoint 1: addr = 0x282963fd0 size = 8 state = enabled type = w
    new value: 4730418656

内存断点发现 set 在执行 addObject 可能会触发 __rehashs 方法,__rehashs 会修改 _set + 0x10 处的值。

#0	0x000000018a64a578 in __rehashs ()
#1	0x000000018a64b96c in -[__NSSetM addObject:] ()
#2	0x0000000102718990 in -[ViewController viewDidLoad] at /Users/yuencong/workplace/Test/Test/ViewController.mm:23

__rehashs 修改 _set + 0x10 上方 0x18a64a568 处有一次 free 的操作:

    0x18a64a564 <+212>: mov    x0, x22
    0x18a64a568 <+216>: bl     0x18a7fc7d0               ; symbol stub for: free
    0x18a64a56c <+220>: ldrsw  x8, [x25, #0x680]
    0x18a64a570 <+224>: add    x8, x20, x8
->  0x18a64a574 <+228>: str    x21, [x8]
    0x18a64a578 <+232>: ldr    w9, [x8, #0xc]
    0x18a64a57c <+236>: bfi    w9, w19, #26, #6
    0x18a64a580 <+240>: str    w9, [x8, #0xc]

再次运行测试代码,查看 free 的值,断点到 0x18a64a568:

    0x18a64a560 <+208>: b.ne   0x18a64a518               ; <+136>
    0x18a64a564 <+212>: mov    x0, x22
->  0x18a64a568 <+216>: bl     0x18a7fc7d0               ; symbol stub for: free
    0x18a64a56c <+220>: ldrsw  x8, [x25, #0x680]
    0x18a64a570 <+224>: add    x8, x20, x8
    0x18a64a574 <+228>: str    x21, [x8]

可以看到 free 的 x22 的值,也是 _set + 0x10 位置的值。

(lldb) reGISter read x22
     x22 = 0x0000000282d245c0
(lldb) _set __NSSetM * 3 elements 0x0000000282d24580
error: '_set' is not a valid command.
(lldb) memory read 0x0000000282d24590
0x282d24590: c0 45 d2 82 02 00 00 00 05 00 00 00 03 00 00 04  .E..............
0x282d245a0: 80 00 32 80 02 00 00 00 00 00 00 00 00 00 00 00  ..2.............

_set +0x10 处是个啥?

打印 OBJC_CLASS$___NSSetM 的 ivars,offset == 0x10 的位置是 storage

ivars          0x593140 __OBJC_$_INSTANCE_VARIABLES___NSSetM
  entsize   32
  count     2
  offset    0x59b3D8 _OBJC_IVAR_$___NSSetM.cow 8
  name      0x39fe21 cow
            type      0x3ff0ab A^{__cow_state_t}
alignment 3
  size      8
  offset    0x59b3d0 _OBJC_IVAR_$___NSSetM.storage 16
  name      0x39fe25 storage
            type      0x400612 {?="objs"^@"state"(?="mutations"Q""{?="muts"I"used"b26"szidx"b6})}
alignment 3
  size      16

这个 type 略长,没有分析具体的类型,但是根据 xcode debug 的信息,可以得知 storage 存储了一个指针,指针指向存储 set item 的数组,这个字段的含义也就比较容易理解了。

结论

NSMutableSet 对象 addObject 可能会触发 __rehashs_rehashs 会释放 storage 指针, enumerateObjectsUsingBlock 会访问 storage 指针,多线程访问的情况下会触发 use-after-free的崩溃。如果存在多线程同时执行 enumerateObjectsUsingBlockaddObject 方法需要保证线程安全

NSMutable 对象共性问题?

尝试了 NSMutableDictionary & NSMutableArray rehash 都有可能会触发 use-after-free。

以上就是NSMutable 对象的坑解决分析的详细内容,更多关于NSMutable 对象坑的资料请关注编程网其它相关文章!

--结束END--

本文标题: NSMutable 对象的坑解决分析

本文链接: https://lsjlt.com/news/197877.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • NSMutable 对象的坑解决分析
    目录背景测试代码_set +0x10 处是个啥?结论NSMutable 对象共性问题背景 最近处理了两个崩溃,都是在 NSMutableSet 调用 enumerateOb...
    99+
    2023-02-28
    NSMutable 对象坑 NSMutable 对象
  • NSMutable对象的坑如何解决
    本文小编为大家详细介绍“NSMutable对象的坑如何解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“NSMutable对象的坑如何解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。背景最近处理了两个崩溃,都...
    99+
    2023-07-05
  • redis保存AtomicInteger对象踩坑及解决
    目录Redis保存AtomicInteger对象踩坑解决方案RedisAtomicInteger的使用redis保存AtomicInteger对象踩坑 redisTemplate 保存AtomicInteger对象异常:...
    99+
    2022-11-22
    redis保存AtomicInteger redis保存AtomicInteger对象 保存AtomicInteger对象踩坑
  • Vue关于对象直接赋值的坑及解决
    目录Vue对象直接赋值的坑Vue对象的赋值Object.assign({}, row)Vue对象直接赋值的坑 受JavaScript的限制,Vue不能监听到对象属性的添加或删除。如果...
    99+
    2024-04-02
  • feignGET请求不支持对象传参的坑及解决
    目录GET请求不支持对象传参问题解决方法feign发get请求遇到的坑问题原因分析加上@RequestParam后问题解决GET请求不支持对象传参 问题 @GetMapping("/...
    99+
    2024-04-02
  • 分析JavaScript的Navigator对象
    这篇文章主要讲解了“分析JavaScript的Navigator对象”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“分析JavaScript的Navigato...
    99+
    2024-04-02
  • JavaScript对象、对象属性、对象方法的示例分析
    这篇文章主要介绍JavaScript对象、对象属性、对象方法的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!JavaScript 变量是数据值的容器。 这段代码把一个单一值...
    99+
    2024-04-02
  • ES6顶层对象、global对象的示例分析
    这篇文章将为大家详细讲解有关ES6顶层对象、global对象的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。顶层对象顶层对象,在浏览器环境指的是window对象,...
    99+
    2024-04-02
  • JavaScript对象的示例分析
    这篇文章将为大家详细讲解有关JavaScript对象的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、构造函数为什么使用构造函数什么是构造函数:是JavaScr...
    99+
    2024-04-02
  • Scala对象的示例分析
    这篇文章主要介绍Scala对象的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Scala作为一个纯面向对象的语言,于是在Scala中万物皆对象,包括数字和函数。在这方面,Scala于Java存在很大不同:Ja...
    99+
    2023-06-17
  • VB.NET对象的示例分析
    这篇文章主要介绍了VB.NET对象的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。对象的生命周期在VB 6中,对象有一个很清楚的定义以及很容易理解的生命周期的概念,对...
    99+
    2023-06-17
  • 使用shardingsphere对SQLServer坑的解决
    背景:最近一个使用SQLServer的项目,业务量太大,开始对业务有影响了,因此用户要求升级改造,技术上采用shardingsphere进行分库分表。 经过一系列调研,设计。。。哐哐...
    99+
    2024-04-02
  • SpringCloud:feign对象传参和普通传参及遇到的坑解决
    目录feign对象传参和普通传参及遇到的坑对象传参普通传参遇到的坑-1遇到的坑-2feign传递复杂参数对象需要注意的地方传递复杂参数对象需要用Post在传递的过程中feign对象传...
    99+
    2024-04-02
  • feign GET请求不支持对象传参的坑怎么解决
    这篇“feign GET请求不支持对象传参的坑怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“feign&n...
    99+
    2023-06-29
  • jquery对象与DOM对象转化的示例分析
    这篇文章主要介绍了jquery对象与DOM对象转化的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。jquery对象是一个集合,相当于...
    99+
    2024-04-02
  • Java对象结构与对象锁的示例分析
    这篇文章主要介绍Java对象结构与对象锁的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1. Java对象结构Java对象结构包括三部分:对象头、对象体和填充字节,如图所示:对象头又包括三个字段:第一个字段叫...
    99+
    2023-06-29
  • JavaScript对象实例分析
    本篇内容介绍了“JavaScript对象实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! Java...
    99+
    2024-04-02
  • ES6对象实例分析
    本篇内容介绍了“ES6对象实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!对象字面量属性的简洁表示法ES6允许对象的属性直接写变量,这...
    99+
    2023-06-27
  • Java对象实例分析
    这篇文章主要介绍“Java对象实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java对象实例分析”文章能帮助大家解决问题。1、寒冬的蛰伏这里的工作很繁忙,一年365天, 一天24小时几乎不停...
    99+
    2023-06-04
  • DAO.NET DataSet对象的示例分析
    这篇文章主要介绍了DAO.NET DataSet对象的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.数据集DataSet概述数据集DataSet是断开与数据源的连...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作