2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

Facebook 调试 iOS 文件损坏的过程

  • 2014-09-11
  • 本文字数:1372 字

    阅读完需:约 5 分钟

Facebook 工程师 Slobodan Predolac 和 Nicolas Spielberg 最近描述了他们如何解决了一个顽固的移动调试问题,并且使崩溃频率降低了50% 以上。在此过程中,他们展示了若干通用的技巧以及Facebook 发开的工具,这些对不断快速增长的大型代码库会有所帮助。

Predolac 和 Spielberg 回顾说,此 bug 开始的时候有点像 Core Data 崩溃。他们首先使用 Facebook 自己的工具 Hipal Scuba 从崩溃日志中查找和搜集数据,分析的结果是 Core Data 错误编码没有统一的规律。

在查找问题的根源时,Facebook 开发软件的方式是阻碍此过程的障碍之一,因为 Facebook 以月为发布周期,而且有数百名开发人员向各发布版本提交代码。所以,这两位工程师在文中描述说,“即使我们能够缩小引入 bug 的时间范围,也无法隔离数千次代码提交来纠错”。况且每次的版本发布都经过 A/B 测试,这就更难区分“到底是代码还是配置导致了该问题”。

证明以上方式行不通后,Facebook 的工程师开始做出不同的假设,在排除了若干假设后,他们试着验证下一个假设,那就是 Core Data 是该问题的根本原因所在。于是他们找到了“一段受影响的代码,他们可以很容易地将这块代码从 Core Data 切换为 SQLite,用以验证他们的假设”。

之后没多久,他们就收到崩溃报告,报告指出某文件被“可恶的线程或进程”重写了。这说明查找问题的方向是正确的,但是在“庞大的代码库中”顺利找到此线程或进程看起来不是一件容易的事情。他们采取的方法是在打开 SQLite 文件之前打开一个诱饵文件,这样就能捕捉到进行写文件操作的线程,然后查看损坏的文件。通过此方法,他们在所有的附件中发现了一个相同的前缀:17 03 03 00 28,然后使用 lldb 中的以下命令设置了一个断点,用以查找试图向 POSIX write() 方法发送此内容的任意线程:

复制代码
breakpoint set -n write -c "(*(char**) ($esp + 8))[0]==0x17
&& (*(char**) ($esp + 8))[1]==0x03
&& (*(char**) ($esp + 8))[2]==0x03
&& (*(char**) ($esp + 8))[3]==0x00
&& (*(char**) ($esp + 8))[4]==0x28"

很快他们发现 SPDY 协议栈很可能就是罪魁祸首,接下来就验证该假设。他们使用 Fishhook 完成了验证的工作,这是 Facebook 开发的一款开源工具,它可以替换系统的 write 调用。

复制代码
// setup a honeypot file
int trap_fd = open(…);
// Create new function to detect writes to the honeypot
static WRITE_FUNC_T original_write = dlsym(RTLD_DEFAULT, "write");
ssize_t corruption_write(int fd, const void *buf, size_t size) {
FBFatal(fd != trap_fd, @"Writing to the honeypot file");
return original_write(fd, buf, size);
}
// Replace the system write with our “checked version”
rebind_symbols((struct rebinding[1]){{(char *)"write", (void *)corruption_write}}, 1);

在第二天他们手中最新的崩溃报告显示,SSL 层在向一个 socket 中写数据,但这个 socket 之前已经被关闭,并且被重新分配给了出问题的数据库文件。

一旦在查明了崩溃的原因,修复问题仅仅花了几个小时就搞定了。

查看英文原文: Debugging iOS File Corruption at Facebook


感谢曹知渊对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014-09-11 02:251603
用户头像

发布了 28 篇内容, 共 12.1 次阅读, 收获喜欢 0 次。

关注

评论

发布
暂无评论
发现更多内容

蕉下招股书里提了26次的DTC,到底是啥?

易观分析

DTC

数字化赋能塑化产业,B2B电商模式引领企业增长新引擎

数商云

产业互联网 数字化转型

数据库性能优化方案

五分钟学大数据

4月月更

Java中IO字符流、File类

爱好编程进阶

Java 面试 后端开发

InfoQ 公开课开放报名,融云场景化低代码平台探究

融云 RongCloud

FTP指的是什么协议?由什么组成?有什么作用?

行云管家

运维 网络协议 服务器 ftp

车联网通信安全之 SSL/TLS 协议|车联网系列专题 06

EMQ映云科技

车联网 物联网 IoT ssl emq

Envoy熔断限流实践(一)基于Rainbond插件实现熔断

北京好雨科技有限公司

Kubernetes PaaS envoy rainbond

Java中高级核心知识全面解析——常用框架(Spring中-Bean-的作用域与生命周期)

爱好编程进阶

Java 面试 后端开发

Java基础知识点总结

爱好编程进阶

Java 面试 后端开发

在Redis中使用Pipelining提升查询速度

CRMEB

IndexedDB 代码封装、性能摸索以及多标签支持

网易云信

JavaScript 数据库

Java之Java特点

爱好编程进阶

Java 面试 后端开发

Java并发之Condition详解

爱好编程进阶

Java 面试 后端开发

Java面试题总结(附答案)

爱好编程进阶

Java 面试 后端开发

打基础丨Python图像处理入门知识详解

华为云开发者联盟

Python OpenCV 图像处理 图像 二值图像

TASKCTL 作业调度节点数超规格处理方法

敏捷调度TASKCTL

开源 DevOps 分布式 方法论 敏捷开发

Java基础 - Eclipse,API,Object常用方法

爱好编程进阶

Java 面试 后端开发

JDK、JRE、JIT

爱好编程进阶

Java 面试 后端开发

服务可用性成险企智能运维关键破局能力,博睿数据APM下场助力

博睿数据

确定还不来看看?这样管理你的代码库既方便又省心!

Jianmu

开源 持续集成 工作流 代码管理 workflow

银行应构建主动式客户体验管理体系,助力客户价值增长

易观分析

银行 客户体验管理

旺链周 | 我们的价值观,我们来代言

旺链科技

区块链 活动 价值观

高层次人才一站式服务平台开发 人才综合服务平台系统

a13823115807

你真的了解IT资产管理系统(ITAM)吗?

低代码小观

资产管理 企业管理系统 CRM系统 企业管理工具 资产安全

Java流程控制语句-分支结构(选择结构)

爱好编程进阶

Java 面试 后端开发

啃论文俱乐部的团队之道和成长之路

PaperResearch

开源 OpenHarmony 啃论文俱乐部 技术自由

【二级等保】二级等保需要做日志审计吗?

行云管家

等保 日志审计 等保2.0 二级等保

Java树结构实际应用(平衡二叉树-AVL树)

爱好编程进阶

Java 面试 后端开发

Go能实现AOP吗?

捉虫大师

Java Go aop 4月月更

从安全和不安全两个角度,教你如何发布对象(含各种单例代码)

华为云开发者联盟

安全 线程 高并发 发布对象 对象溢出

Facebook调试iOS文件损坏的过程_Meta_Sergio De Simone_InfoQ精选文章