欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~

本文由 微信终端开发团队团队发布在腾讯云+社区

前言

相信大家都遇到过一段特殊文本可以让iOS设备所有app闪退的经历。前段时间大年初一,又出现某个印度语字符引起iOS11系统奔溃。所幸微信客户端做了保护并没有引起太大问题。一般来说,特殊字符闪退是系统漏洞引起,只要更新系统就行。但大部分用户不愿意更新系统,而苹果也不一定第一时间解决问题。另外后台可以拦截恶意文本传递,但对于本地已下发的消息,后台没有办法让它删除。所以客户端还是要做些保护预防特殊字符闪退。

方案

由于无法事先知道字符串里包含特殊字符,所以只能先让它排版/绘制,看看是否出现问题。做法是,在排版/绘制字符串前,先设置标记位,排版/绘制结束后,移除标记位;一旦发现标记位存在,就意味着这字符串可能有问题,下次就不显示这个字符串:

这里有几个问题:

  1. 有可能在排版/绘制过程中,其它线程crash,导致标记位不能正常移除。所以crash时要判断crash线程是否为排版/绘制线程。
  2. 究竟crash多少次才能判断这字符串是有问题的。最早做法是crash一次就直接屏蔽,但很多用户反馈,说某些好友昵称无法显示。其实iOS绘制字符串时也会极少概率出现闪退,从而误判。但crash两次才屏蔽的话,如果用户连续收到N条恶意消息,那么至少crash 2N次才彻底把所有有问题消息屏蔽。因此,第一次字符串crash先不屏蔽,后续连续字符串crash的话,直接屏蔽。这样crash N+1次就能处理完了。

整个逻辑代码大致如下:

// MessageItemView.mm, CP是CrashProtected的简称@implementation MessageItemView- (void)initContentLabel {m_label = [[MMCPLabel alloc] init];m_label.cpKey = [MMCPUtil generateKeyWithObject:self.messageModel];if ([MMCPUtil isUnsafeWithKey:m_label.cpKey]) {// 检测出messageModel消息内容有问题,屏蔽显示m_label.text = @"该内容无法显示";} else {m_label.text = self.messageModel.content;}
}@end
// MMCPLabel.mm@implementation MMCPLabel@synthesize cpKey = m_cpKey;// 对常用的排版/绘制接口做检查
- (void)layoutSublayersOfLayer:(CALayer *)layer {CScopedCrashCounter crashCounter(m_cpKey);[super layoutSublayersOfLayer:layer];
}- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {CScopedCrashCounter crashCounter(m_cpKey);[super drawLayer:layer inContext:ctx];
}- (CGSize)sizeThatFits:(CGSize)size {CScopedCrashCounter crashCounter(m_cpKey);return [super sizeThatFits:size];
}@end
// MMCPUtil.mm// 利用C++特性,在声明C++类临时变量时,会自动执行构造函数,离开作用域会执行析构函数
// 因此构造函数做crashCount+1,析构函数做crashCount-1
class CScopedCrashCounter {
public:CScopedCrashCounter(NSString *cpKey) {m_cpKey = cpKey;[MMCPUtil increaseCrashCountWithKey:m_cpKey];}~CScopedCrashCounter() {[MMCPUtil decreaseCrashCountWithKey:m_cpKey];}
private:NSString *m_cpKey;
};@implementation MMCPUtil@synthesize crashKeyMemoryMappedKV = m_crashKeyMemoryMappedKV; // 被判定为恶意信息对应的key
@synthesize crashCountMemoryMappedKV = m_crashCountMemoryMappedKV; // 每个key crash次数- (BOOL)isUnsafeWithKey:(NSString *)key {return [m_crashKeyMemoryMappedKV getBoolForKey:key] == YES;
}- (void)increaseCrashCountWithKey:(NSString *)key {// 这里记录key所在线程...int32_t count = [m_crashCountMemoryMappedKV getInt32ForKey:key];[m_crashCountMemoryMappedKV setInt32:count + 1 forKey:key]
}- (void)decreaseCrashCountWithKey:(NSString *)key {int32_t count = [m_crashCountMemoryMappedKV getInt32ForKey:key];[m_crashCountMemoryMappedKV setInt32:MAX(0, count - 1) forKey:key];
}// crash回调函数
- (void)onSignalCrash:(siginfo_t *)info {// 先找到跟crash线程相同的keyNSString *key = [self lastCPKey:info->si_pid];if (key == nil) return;if (m_isLastTimeCrashedBySpecialCharacter == NO) {// 设置当前是特殊字符引起的闪退,如果crash次数大于1,则屏蔽这字符串显示[self setLastTimeCrashedBySpecialCharacter:YES];if ([m_crashCountMemoryMappedKV getInt32ForKey:key] > 1) {[m_crashKeyMemoryMappedKV setBool:YES forKey:key];}} else {// 连续特殊字符闪退,直接屏蔽[m_crashKeyMemoryMappedKV setBool:YES forKey:key];}
}@end

即使有了上面的N+1优化,当N很大时,客户端还是要crash很多次才能正常使用。之前有用户乱扫二维码被拉进炸群,如果不发红包,群主不停炸群;用户频繁crash,也无法退群。不少用户会选择卸载重装客户端。因此客户端要加上安全模式的机制。当客户端检测出连续三次crash,下次启动会出现安全模式的界面,提示用户如何处理:

对于频繁闪退的群聊,主界面提供快捷入口方便用户退群。另外对于可能误判的字符串,界面也提供入口方便用户恢复字符串显示:

为了让后台第一时间发现新的特殊字符变种,客户端检测出特殊字符crash后,会把相关信息上报到后台。通过客户端上报、后台拦截的闭环,能大大降低特殊字符传播范围。这方案不仅用于特殊字符,还能用于其他恶意信息,如炸群消息、GIF、小视频、链接等。

MemoryMappedKV

由于需要埋点的地方太多了,昵称、消息内容、头像等等,为了不影响滑动性能,guoling同学开发了一套基于mmap的高性能通用key-value存储组件,敬请留意WeMobileDev后续文章。

问答

短视频的发展前景以及未来发展方向?

更多与短视频相关的精华问答,尽在腾讯云+社区!

相关阅读

谈谈编程

程序员字典:「牛逼」

码云推荐 | Symphony 社区平台的微信小程序

此文已由作者授权腾讯云+社区发布,转载请注明文章出处

原文链接:https://cloud.tencent.com/dev...

大年初一微信闪退?看看如何修复的相关推荐

  1. 大年初一微信闪退?看看如何修复的 1

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由 微信终端开发团队团队发布在腾讯云+社区 前言 相信大家都遇到过一段特殊文本可以让iOS设备所有app闪退的经历.前段时间大年初一,又 ...

  2. iphone闪退修复工具_升级 iOS 14.2 微信闪退?iPhone 12 维修贵

    原标题:升级 iOS 14.2 微信闪退?iPhone 12 维修贵 昨天,苹果推出 iOS 14.2 正式版系统,我相信你们都知道了,主要新增几点功能,并没有针对性解决耗电问题,而对 AirPods ...

  3. 微信闪退Bug罪魁祸首竟是二维码引擎,附源代码分析

    建议别尝试:转发这个二维码到群里,3秒后你会回来骂我(抖m求骂) 近日,网传微信识别上方二维码就会出现闪退BUG,小编也忍不住尝试了一下,果然,一识别该二维码微信立马就出现了闪退的现象: 且会出现&q ...

  4. iPhone 14微信闪退怎么办?iPhone 14微信闪退解决办法分享

    大家在iPhone上使用微信的时候肯定都有遇到过微信闪退的情况,闪退问题一旦出现,就会严重影响我们的正常使用,特别是使用频繁的APP. iPhone 14微信闪退是什么原因造成的?iPhone 14微 ...

  5. 神秘代码让iPhone微信闪退的解决方法

    14号晚,很多人的微信朋友圈中出现了这样几句话"听说苹果手机点全文就会闪退",下方有好几行空白,需要点击"全文"才能看到,但是一旦你是在iPhone手机微信上点 ...

  6. MacOs 12 微信闪退

    升级了6月8号发布的mac OS 12 Monterey 系统 Mac 微信闪退问题 微信和微信开发者工具闪退,官方已紧急修复,下载链接如下 我的电脑是Mac Book Pro 2020 M1芯片,亲 ...

  7. 微信 android 闪退问题怎么解决方法,如何解决微信闪退问题 四种解决微信闪退无法登录的原因及方法分享...

    微信闪退无法登录怎么办?现在使用微信的用户越来越多,即方便又快捷,有的朋友在使用时候可能会遇到微信闪退无法登陆的情况,今天小编为大家带来了四种解决微信闪退无法登录的原因及方法分享,感兴趣的朋友快来了解 ...

  8. 谷歌老闪退啊 和 pycharm版本问题 and 微信闪退

    我清了浏览记录也没用 感觉这2个方法靠谱点,还没用过 设置里面:选择高级-时间限然后开始清理 或者设置面板中点高级-重置并清理 或者重启 https://jingyan.baidu.com/artic ...

  9. android 三星闪退,三星手机升级安卓10微信闪退怎么办?(附解决方法)

    随着开发的完善,三星近期陆续向用户推送了安卓 10 系统.能用上新系统,用户自然兴奋期待.可是这安卓 10 却没能给用户带来更顺畅的体验,反倒惹了一些麻烦.不少用户反馈,自己手上的三星手机,更新到安卓 ...

最新文章

  1. pandas使用pd.concat纵向合并多个dataframe实战:纵向合并(ignore_index参数)、为纵向合并的多个dataframe设置标识符指定数据来源(通过字典方式设置数据来源键)
  2. Windows Azure Cloud Service (19) 动态指定WCF的发布地址
  3. Android学习笔记:ScrollView卷轴视图
  4. 用初中数学题理解SVM中不等式约束、拉格朗日乘子法、kkt条件、对偶
  5. 【操作系统】多道程序的理解
  6. [Linux] 解决Ubuntu12.10 64位google chrome安装Flash后出现couldn‘t load plug-in的问题;
  7. [HNOI2013]题解
  8. Jmeter --- Http Cookie Manager
  9. java byte[]如何移动位置_《北京尚学堂学习》——java基础
  10. syslog日志转换器_图解将windows日志转成syslog格式并发送
  11. 递归下降分析程序的设计和实现
  12. windows系统镜像修复计算机,Win10系统下修复Windows映像方法
  13. 亿格瑞A5-hdmi故障了
  14. grpc-go 连接backoff协议
  15. 笔记本固态硬盘和普通硬盘的区别
  16. [TOG2022]DCT-Net: Domain-Calibrated Translation for Portrait Stylization
  17. 实战演练 | MySQL PROCESSLIST 表和 Navicat Monitor 识别慢速查询的简单方法
  18. myeclipse的server视图经常报nullpoint
  19. 基于图像的三维建模——特征点检测与匹配
  20. Idea内存占用过高解决方法

热门文章

  1. 又是逆袭!大四在校生 6 个月拿下京东美团滴滴等 Offer
  2. 漫画:程序员太难了!为什么 Java 中的 main 方法必须是它?
  3. Linux 多版本python3、python2共存安装
  4. 三种途径助物联网改变业务 省心省时省成本
  5. Linux系统查看系统是32位还是64位方法总结 in 创新实训
  6. Myeclipse常用快捷键
  7. 京东网络开放之路——自研交换机探索与实践
  8. IOS开发 使用CGContextRef绘制文字时的设置
  9. 如何查看Linux系统下程序运行时使用的库?
  10. 极客Web前端开发资源大荟萃#007