在Objective-C中由于整数溢出而处理和报告内存分配错误的最佳方法是什么?

Qui*_*lor 9 memory-management error-reporting objective-c integer-overflow

首先,让我说我理解我所描述的问题是如何以及为什么会发生的.我是计算机科学专业,我理解溢出/下溢和签名/无符号算术.(对于那些不熟悉该主题的人,Apple的安全编码指南会简要讨论整数溢出.)

我的问题是关于在检测到这种错误后报告和恢复,更具体地说是在Objective-C框架的情况下.(我编写和维护CHDataStructures.)我有一些集合类,它们分配用于存储对象的内存并根据需要动态扩展.我还没有看到任何与溢出相关的崩溃,可能是因为我的测试用例主要使用了理智的数据.但是,给定未经验证的值,事情可能会很快爆炸,我想阻止它.

我已经确定了至少两种可能发生这种情况的常见情况:

  1. 调用者将非常大的无符号值(或负符号值)传递给-initWithCapacity:.
  2. 添加了足够的对象以使容量动态扩展,并且容量已经增大到足以导致溢出.

简单的部分是检测是否会发生溢出.(例如,在尝试分配length * sizeof(void*)字节之前,我可以检查是否length <= UINT_MAX / sizeof(void*),因为未通过此测试将意味着产品将溢出并可能分配比预期更小的内存区域.在支持它的平台上,checkint.h API是另一种选择.)更难的部分是确定如何优雅地处理它.在第一种情况下,呼叫者可能更好地(或至少在思维模式中)处理故障.第二种情况可能发生在代码中将对象添加到集合中的任何位置,这可能是非常不确定的.

那么,我的问题是:在这种情况下,当整数溢出发生时,"好公民"Objective-C代码如何表现?(理想情况下,由于我的项目是一个与Cocoa中的Foundation基本相同的框架,我想建模它的行为方式以获得最大的"阻抗匹配".我发现的Apple文档中没有提及太多所有这一切.)我认为,无论如何,报告错误是给定的.由于添加对象的API(可能导致方案2)不接受错误参数,我可以做些什么来帮助解决问题,如果有的话?在这种情况下,真正考虑的是什么?如果我能做得更好,我不愿意故意编写容易崩溃的代码......

bbu*_*bum 3

目前有两个问题:

(1) 分配失败并且内存不足。

(2) 您检测到溢出或其他错误情况,如果继续,将导致 (1)。

在(1)的情况下,你会被彻底击垮(除非失败的分配非常大并且你知道失败的分配只是那个)。如果发生这种情况,你能做的最好的事情就是尽快坠毁并留下尽可能多的证据。特别是,创建一个调用abort()类似名称的函数IAmCrashingOnPurposeBecauseYourMemoryIsDepleted()会在崩溃日志中留下证据。

如果确实是(2),那么还有其他问题。具体来说,您能否从这种情况中恢复,并且无论如何,用户的数据是否仍然完好无损?如果你可以恢复,那么伟大......这样做,用户永远不必知道。如果没有,那么您需要绝对确保用户的数据没有损坏。如果不是,那就保存并死亡。如果用户的数据已损坏,请尽力不保留损坏的数据,并让用户知道出现了严重错误。如果用户的数据已经被持久化,但已损坏,那么...好吧...哎呀...您可能需要考虑创建某种恢复工具。