3

我在我的 iOS 项目中使用PLCrashReporter,我很好奇,是否可以在我的自定义崩溃回调中使用 Core Foundation 代码。处理我需要的东西是 CFPreferences。这是我创建的代码的一部分:

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);
}

我的目标是在应用程序崩溃时收集一些系统信息,例如互联网连接类型。

我知道由于异步安全函数而创建自己的崩溃回调不是一个好主意,但这会有所帮助。

也作为其他选项:有没有办法以某种方式扩展 PLCrashReportSystemInfo 类?

4

1 回答 1

3

这是非常危险的。特别是调用CFStringCreateWithFormat分配内存。在崩溃处理程序中间分配内存可能会导致电池耗尽死锁(是的;有那个错误……)例如,如果你在中间free()(这不是一个不常见的崩溃地方),你可能已经持有堆上的自旋锁。当您调用malloc以获取一些内存时,您可能会再次自旋锁堆并在紧密循环中死锁。堆需要如此频繁且如此短的时间被锁定,以至于它不使用阻塞锁。它相当于while (locked) {}.

您似乎只是在阅读首选项并将其复制到另一个首选项。没有理由在崩溃处理程序中这样做。只需hasPendingCrashReport在启动期间检查(我假设您已经这样做了),然后阅读密钥。目前尚不清楚是什么networkStatusKey,但当你再次启动时它应该仍然存在。

如果由于任何原因它很早就被修改了(在你打电话之前),你可以在启动应用程序之前hasPendingCrashReport抓住它。main()或者您可以在+load更早调用的方法中获取它。

于 2015-05-26T14:45:40.113 回答