我有一个使用LaunchAgent进行崩溃报告的HockeyApp。现在我注意到,在HockeyApp没有报告的情况下,就像在一个普通的macOS应用程序中一样,这是一个不寻常的例外。
例如:
- (void)upperCaseString:(NSString *)aString withReply:(void (^)(NSString *))reply {
NSArray *array = [NSArray array];
reply([array objectAtIndex:23]);
}从未到达NSUncaughtExceptionHandler,但控制台记录:
<NSXPCConnection: 0x7fe97dc0f110> connection from pid 44573: Warning: Exception caught during invocation of received message, dropping incoming message and invalidating the connection.问题是如何用HockeyApp报告未处理的异常。
发布于 2019-03-03 09:22:49
问题:
XPC似乎有自己的@try @catch块,它捕获方法中未处理的异常,记录异常,然后调用-[NSXPCConnection interruptionHandler]。
这个问题是在雷达://48543049下向苹果报告的。
注意:--这些是而不是复制和过去的解决方案,仔细评估崩溃报告框架。我链接到PLCrashReporter的实现细节。
解决方案A:
@try @catch块
- (void)upperCaseString:(NSString *)aString withReply:(void (^)(NSString *))reply {
@try {
NSArray *array = [NSArray array];
reply([array objectAtIndex:23]);
} @catch (NSException *exception) {
NSUncaughtExceptionHandler *handler = NSGetUncaughtExceptionHandler();
if (handler) {
handler(exception);
}
}
}讨论
HockeyApp使用PLCrashReporter进行崩溃报告。PLCrashReporter注册一个NSUncaughtExceptionHandler (代码)。因此,上面的代码将把异常转发给PLCrashReporter异常处理程序,并终止(代码) XPC。
马蒂建议再次@抛出异常,以触发内部XPC @catch块和可能的内部清理和日志记录。,这是值得考虑的事情,。特别是如果您在连接的LaunchAgent/Server端的NSXPCConnection上有一个自定义的NSXPCConnection!
现在,我不想再次抛出它,因为--我的 XPC是完全无状态的,只要崩溃就可以了。
解决方案A的缺点是,通过XPC公开的每个方法都需要这个@try @块。
解决方案B:
使用NSProxy将所有未处理的异常捕获为NSXPCConnection exportObject
@interface LOUncaughtExceptionHandlerProxy : NSProxy {
NSObject *_object;
}
@end
@implementation LOUncaughtExceptionHandlerProxy
- (instancetype)initWithObject:(NSObject *)object
{
NSParameterAssert(object);
_object = object;
return self;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
return [_object methodSignatureForSelector:selector];
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
@try {
[invocation invokeWithTarget:_object];
} @catch (NSException *exception) {
NSUncaughtExceptionHandler *handler = NSGetUncaughtExceptionHandler();
if (handler) {
handler(exception);
}
}
}
@end在NSXPCListener侦听器中设置:
- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
XPC *exportedObject = [XPC new];
LOUncaughtExceptionHandlerProxy *proxy = [[LOUncaughtExceptionHandlerProxy alloc] initWithObject:exportedObject];
newConnection.exportedObject = proxy;
newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(XPCProtocol)];
[newConnection resume];
return YES;
}解决方案A的所有细节都适用于解决方案B。
解决方案Z:
在macOS上可以使用ExceptionHandling.framework,它的问题在BITCrashExceptionApplication.h中得到了很好的描述。
讨论
当一个框架没有移植到iOS时,这绝不是一个好迹象。还请注意马蒂的评论:
我与苹果的互动直接表明ExceptionHandling.framework不再受支持。而且,在我研究Crashlytics的过程中,除了在引用的标题中指出的之外,它还有一些基本的互操作性问题。
https://stackoverflow.com/questions/54967355
复制相似问题