我在我的iOS项目中使用PLCrashReporter并且我很好奇,是否可以在我的自定义崩溃回调中使用Core Foundation代码。处理我需求的是CFPreferences.Here是我创建的代码的一部分:
void LMCrashCallback(siginfo_t* info, ucontext_t* uap, void* context) {
CFStringRef networkStatusOnCrash;
networkStatusOnCrash = (CFStringRef)CFPreferencesCopyAppValue(networkStatusKey, kCFPreferencesCurrentApplication);
CFStringRef additionalInfo = CFStringCreateWithFormat(
NULL, NULL, CFSTR( "Additional Crash Properties:[Internet: %@]", networkStatusOnCrash);
CFPreferencesSetAppValue(additionalInfoKey, additionalInfo,
kCFPreferencesCurrentApplication);
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
}
我的目标是收集一些系统信息,就在应用程序崩溃的时候,例如Internet连接类型。
我知道由于异步安全函数而创建自己的崩溃回调并不是一个好主意,但这可能有所帮助。
另外还有其他选择:有没有办法以某种方式扩展PLCrashReportSystemInfo类?
答案 0 :(得分:3)
这非常危险。特别是对CFStringCreateWithFormat
的调用分配内存。在崩溃处理程序中间分配内存会导致电池耗尽死锁(是的;有那个错误...)例如,如果你在free()
(这不是一个不常见的崩溃地点)的中间,你可能已经在堆上持有一个螺旋锁。当你调用malloc
获取一些内存时,你可能会再次自动锁定堆并在紧密循环中死锁。堆需要经常锁定,并且在如此短的时间内不会使用阻塞锁。它相当于while (locked) {}
。
您似乎只是在阅读偏好并将其复制到另一个偏好。在崩溃处理程序中没有理由这样做。只需在启动期间检查hasPendingCrashReport
(我假设您已经做过),然后阅读密钥。我不清楚networkStatusKey
是什么,但是当你重新开始时它应该仍然存在。
如果由于任何原因它很早就被修改(在您致电hasPendingCrashReport
之前),您可以在启动应用之前在main()
中抓取它。或者您可以使用+load
方法获取它,甚至可以更早地调用它。