ios 16上new/delete不匹配导致的崩溃

问题描述:

在 ios 16 的某些 iphone 上会发生崩溃,非必先,但是在某些用户机器上会反复出现。

崩溃堆栈:

libsystem_kernel.dylib 0x00000001cc336200 __pthread_kill + 8

libsystem_pthread.dylib 0x00000001dc5731a8 pthread_kill + 268

libsystem_c.dylib 0x000000019712dc9c abort + 180

libsystem_malloc.dylib 0x000000019de52544 0x000000019de35000 + 120136

libsystem_malloc.dylib 0x000000019de5271c 0x000000019de35000 + 120608

libsystem_malloc.dylib 0x000000019de36478 free + 300

libc++.1.dylib 0x000000019dff22f0 std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::__grow_by_and_replace(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, char const*) + 256

libc++.1.dylib 0x000000019dff30a4 std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::append(char const*, unsigned long) + 112

Project 0x0000000100f9a308 -[AFSDKmacOSKeychain timeIntervalForKey:] + 149676

Project 0x0000000100fb10b0 -[AFSDKmacOSKeychain timeIntervalForKey:] + 243284

Project 0x0000000100fb0f40 -[AFSDKmacOSKeychain timeIntervalForKey:] + 242916

libdispatch.dylib 0x00000001970c9fd8 0x00000001970c6000 + 16348

libdispatch.dylib 0x00000001970cb824 0x00000001970c6000 + 22568

Project 0x0000000100fb0f00 -[AFSDKmacOSKeychain timeIntervalForKey:] + 242852

Project 0x0000000100f798d8 -[AFSDKmacOSKeychain timeIntervalForKey:] + 15996

Project 0x0000000100f780c8 -[AFSDKmacOSKeychain timeIntervalForKey:] + 9836

Project 0x0000000100fcaf7c void std::__1::vector<std::__1::pair<void*, API_TYPE>, std::__1::allocator<std::__1::pair<void*, API_TYPE>>>::__push_back_slow_path<std::__1::pair<void*, API_TYPE>>(std::__1::pair<void*, API_TYPE>&&) + 70336

Project 0x0000000100f8c2f4 -[AFSDKmacOSKeychain timeIntervalForKey:] + 92312

libdispatch.dylib 0x00000001970c84b0 0x00000001970c6000 + 9396

libsystem_pthread.dylib 0x00000001dc56cdb8 _pthread_wqthread + 228

排查过程:

最早是在 ios 18 上发现了这个问题,当时这个问题在 ios18 下面是必现的。

通过查资料,发现这个崩溃主要原因在于string调用的 new 和 delete 不成对造成的,new是调用的ue自己的分配器,delete调用的是系统 libc 的分配器,从而导致崩溃。

大概描述如下面这个资料:

我们当时按照 ue 的官方支持的方法,修改了下面的方法,成功解决了 ios 18 下面的这个崩溃。

修改了 IOSToolChain.cs:1480,将

string StripArguments = BinaryLinkEnvironment.bIsBuildingDLL ? “-x -S -D” : “”;

修改为

string StripArguments = “-x -S -D”

修改之后的下一个版本, ios 18 上不再有这个报错,但是 ios 16 上开始大量出现这个报错。

通过查阅资料发现这可能是 ios 16 的一个 bug:

https://www.toutiao.com/article/7481217528024138251/?is\_new\_connect\=0\&is\_new\_user\=0\&wid\=1748485068504

然后我们尝试修改了 IOSToolChain.cs 中的 GetLinkArguments_Global 函数,在函数末尾添加了下面的参数,用以让 linker 不要替换掉 ue 自己的 new 和 delete。

Result += " -Wl,-U,___Znwm";

Result += " -Wl,-U,___ZdaPv";

但是修改后新版本上线后,问题依旧,堆栈还是类似,在系统的 libc 的 free 函数中会发生崩溃,感觉还是没有正确调用 ue 的 delete。

所以想知道我们这边有没有类似的问题的解决方案可以参考。

Hi,有个客户反馈有个修改,可以试试,我放在附件里。我们自己没法验证,如果这个办法仍然不行,只能先用ansi的allocator了,之前在继续想办法。