==44088==ERROR: AddressSanitizer: stack-buffer-overflow

==44088==ERROR: AddressSanitizer: stack-buffer-overflow

我的项目仅 swift(至少对于我编写的代码而言)。在应用程序启动时,我下载了一些 json 来显示内容。我用 swift 4 Coder protocol 反序列化此内容。这已经工作了一段时间,但刚才我收到了一个意外的堆栈缓冲区溢出错误:

==44088==ERROR: AddressSanitizer: stack-buffer-overflow

在后台线程之一反序列化其中一个对象时。

基于此,我有2个问题

如何确保不再发生这种情况?

有没有办法重现它?

更多信息:

我有这个总结,但我不知道该怎么做:

SUMMARY: AddressSanitizer: stack-buffer-overflow JsonClass.swift in _T06MyApp11JsonClassVACs7Decoder_p4from_tKcfC Shadow bytes around the buggy address: 0x100026a904d0: 00 02 f2 f2 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 0x100026a904e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100026a904f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100026a90500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100026a90510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x100026a90520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00[f2]f2 0x100026a90530: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 00 00 0x100026a90540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100026a90550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100026a90560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x100026a90570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb

编辑:

每次都重现(在模拟器中)。然后我清理了构建并删除了派生数据文件夹,此后就再也没有发生过。我仍然想知道我是否需要担心生产中的错误...

首先简单回答一下大家的问题

How can I ensure this doesn't happen again?

您可以修复此特定缺陷并编写单元测试以防止出现回归。然而,一般来说,错误是会发生的;您无法阻止它们,只能减轻它们。使用工具和警告来尽早尝试识别它们。您已经通过使用 Address Sanitizer 做了一件好事(您还应该查看 Undefined Behavior Sanitizer 和 Thread Sanitizer)。

Is there a way to reproduce it?

Address Sanitizer 会在 100% 的情况下报告它。不幸的是,这听起来取决于您使用的是什么数据。也许尝试一些格式错误的数据来尝试哄骗它发生。您可以使用各种类型的数据编写单元测试(确保在启用 Asan 的情况下构建测试)。不看代码就不能多说了。

有什么问题?

你肯定有问题。 Asan 不报告误报。听起来它可能只发生在坏数据上,但你永远不应该相信你总是会有好数据。

在不看代码的情况下帮助您解决问题并不容易。 Asan 报告堆栈缓冲区溢出通常是以下情况之一(根据我的经验):

  1. 在堆栈上分配一个变量并保留对它的引用。当分配它的堆栈帧被销毁时,引用不再有效。
  2. 堆栈上有一个数组并越界。
  3. (很少)将堆栈对象不正确地转换为更大的对象并访问超出堆栈顶部的“成员”。

如果您 运行 虽然 Xcode 它应该会在 Asan 中止时中断。您应该能够看到堆栈跟踪并找到代码中发生这种情况的位置。

帮助识别问题的其他工具

  1. 编译器警告

尽可能多地打开它们。通常,当您执行诸如引用具有自动存储持续时间的内容时,编译器会警告您。

  1. Clang 静态分析器

这也内置于 Xcode 中,可以通过 Product -> Analyize 菜单 运行。这应该填充它在 Xcode 左栏的“问题导航器”中找到的问题。 Clang 非常擅长识别内存错误