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

热烈欢迎我们赶赴百度云+街道社区,以获取更多百度海量数据技术课堂教学蔬果哦~

责任编辑由QQ终端产品开发项目组项目组发布在百度云+街道社区

序言

相信我们都碰到过几段特殊文档能让iOS设备大部份app维托县的经历。前几日除夕夜,又再次出现某一印地语字符串引发iOS11控制系统云讷。幸好QQ应用程序做了为保护并没引发太大难题。一般而言,转义维托县是控制电脑病毒引发,只要预览控制系统xml。但大部分使用者不愿意预览控制系统,而苹果公司也不一定第一时间解决难题。另外前台能截击蓄意文档传达,但对于邻近地区已印发的最新消息,前台没办法让它删掉。因此应用程序还是要做些为保护防治转义维托县。

方案

由于难以预先知道数组里包涵转义,因此只能先让它排印/绘出,看一看与否再次出现难题。作法是,在排印/绘出数组前,先增设记号位,排印/绘出结束后,去除记号位;一旦发现记号位存在,就意味着这数组可能有难题,到时候就不表明这个数组:

这里有几个难题:

有可能在排印/绘出过程中,其他缓存crash,导致记号位不能正常去除。因此crash时要推论crash缓存与否为排印/绘出缓存。究竟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; // 对常见的排印/绘出USB做检查 – (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缓存相同的key NSString *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存储组件,敬请留意云+街道社区先期文章。

问答

如何看待QQ小程序开放插件功能?更多相关的精华问答,尽在百度云+街道社区!

相关阅读

谈谈编程程序员字典:「牛逼」码云推荐 | Symphony 街道社区平台的QQ小程序

此文已由作者授权百度云+街道社区发布,转载请注明文章出处

原文链接:https://cloud.tencent.com/developer/article/1066209

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 290004051@qq.com 举报,一经查实,本站将立刻删除。
如若转载,请注明出处:https://www.wuctw.com/15620.html