I have a method similar to tee utility. He receives a notification that the data has been read on the channel, and then writes data to one or more channels (connected to slave applications). If the subordinate application crashes, then this channel is interrupted, and of course I get an exception, which is then processed in the @try ... @catch block.
This works most of the time. I am puzzled that sometimes an exception completely disables the application with an uncaught exception and points to the writeData line. I could not understand what a pattern is when it falls, but why should it never be caught? (Note that this is not done inside the debugger.)
Here is the code:
//in setup: [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tee:) name:NSFileHandleReadCompletionNotification object:fileHandle]; -(void)tee:(NSNotification *)notification { // NSLog(@"Got read for tee "); NSData *readData = notification.userInfo[NSFileHandleNotificationDataItem]; totalDataRead += readData.length; // NSLog(@"Total Data Read %ld",totalDataRead); NSArray *pipes = [teeBranches objectForKey:notification.object]; if (readData.length) { for (NSPipe *pipe in pipes { @try { [[pipe fileHandleForWriting] writeData:readData]; } @catch (NSException *exception) { NSLog(@"download write fileHandleForWriting fail: %@", exception.reason); if (!_download.isCanceled) { [_download rescheduleOnMain]; NSLog(@"Rescheduling"); } return; } @finally { } } }
I should mention that I installed a signal handler in my AppDelegate> appDidFinishLaunching:
signal(SIGPIPE, &signalHandler); signal(SIGABRT, &signalHandler ); void signalHandler(int signal) { NSLog(@"Got signal %d",signal); }
And it really leads to the application crashing or signal. Here is an example of a reverse stroke:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Application Specific Information: *** Terminating app due to uncaught exception 'NSFileHandleOperationException', reason: '*** -[NSConcreteFileHandle writeData:]: Broken pipe' abort() called terminating with uncaught exception of type NSException Application Specific Backtrace 1: 0 CoreFoundation 0x00007fff838cbbec __exceptionPreprocess + 172 1 libobjc.A.dylib 0x00007fff90e046de objc_exception_throw + 43 2 CoreFoundation 0x00007fff838cba9d +[NSException raise:format:] + 205 3 Foundation 0x00007fff90a2be3c __34-[NSConcreteFileHandle writeData:]_block_invoke + 81 4 Foundation 0x00007fff90c53c17 __49-[_NSDispatchData enumerateByteRangesUsingBlock:]_block_invoke + 32 5 libdispatch.dylib 0x00007fff90fdfb76 _dispatch_client_callout3 + 9 6 libdispatch.dylib 0x00007fff90fdfafa _dispatch_data_apply + 110 7 libdispatch.dylib 0x00007fff90fe9e73 dispatch_data_apply + 31 8 Foundation 0x00007fff90c53bf0 -[_NSDispatchData enumerateByteRangesUsingBlock:] + 83 9 Foundation 0x00007fff90a2bde0 -[NSConcreteFileHandle writeData:] + 150 10 myApp 0x000000010926473e -[MTTaskChain tee:] + 2030 11 CoreFoundation 0x00007fff838880dc __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12 12 CoreFoundation 0x00007fff83779634 _CFXNotificationPost + 3140 13 Foundation 0x00007fff909bb9b1 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66 14 Foundation 0x00007fff90aaf8e6 _performFileHandleSource + 1622 15 CoreFoundation 0x00007fff837e9ae1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 16 CoreFoundation 0x00007fff837dbd3c __CFRunLoopDoSources0 + 476 17 CoreFoundation 0x00007fff837db29f __CFRunLoopRun + 927 18 CoreFoundation 0x00007fff837dacb8 CFRunLoopRunSpecific + 296 19 HIToolbox 0x00007fff90664dbf RunCurrentEventLoopInMode + 235 20 HIToolbox 0x00007fff90664b3a ReceiveNextEventCommon + 431 21 HIToolbox 0x00007fff9066497b _BlockUntilNextEventMatchingListInModeWithFilter + 71 22 AppKit 0x00007fff8acf5cf5 _DPSNextEvent + 1000 23 AppKit 0x00007fff8acf5480 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 194 24 AppKit 0x00007fff8ace9433 -[NSApplication run] + 594 25 AppKit 0x00007fff8acd4834 NSApplicationMain + 1832 26 myApp 0x00000001091b16a2 main + 34 27 myApp 0x00000001091ab864 start + 52
source share