Core Foundation可以在PLCrashReporter信号回调中使用吗?

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

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

我知道创建自己的崩溃回调并不是一个好主意,因为异步安全函数,但这有助于解决问题。

另外还有一个选项:是否有一种方法可以扩展 PLCrashReportSystemInfo 类?

1个回答

3
这非常危险。特别是调用CFStringCreateWithFormat会分配内存。在崩溃处理程序中分配内存可能导致耗电死锁(是的,我曾经遇到过这个问题…)。例如,如果你正在free()中间(这不是一个罕见的崩溃位置),你可能已经在堆上持有自旋锁。当你调用malloc获取一些内存时,你可能会再次自旋锁定堆并在紧密循环中死锁。堆需要频繁地锁定,并且锁定时间非常短,因此它不使用阻塞锁。它执行等价于while (locked) {}的操作。
你似乎只是读取一个首选项并将其复制到另一个首选项。没有理由在崩溃处理程序中这样做。只需在启动期间检查hasPendingCrashReport(我假设你已经在这样做了),然后读取键值。不清楚networkStatusKey是什么,但在下一次启动时应该还在那里。
如果由于某种原因它在很早的时候被修改(在调用hasPendingCrashReport之前),你可以在启动应用程序之前在main()中获取它。或者你可以在一个+load方法中获取它,这个方法甚至更早被调用。

很棒的回答。非常感谢。 - Foriger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接