I seem to get a lot of crash reports like this:
Crashed Thread: 14
Exception Type: EXC_GUARD
Exception Codes: 0x4000000200000000, 0x00007fff96f73c48
Thread 14 Crashed:
0 libsystem_kernel.dylib 0x00007fff97b7213a dup + 10
1 com.apple.Foundation 0x00007fff8a116cee -[NSConcreteTask launchWithDictionary:] + 2457
2 com.mycompany.myapp 0x0000000100022814 +[MCSoftwareUpdate automaticallyCheckForUpdates] + 352
3 com.apple.Foundation 0x00007fff89fed76b __NSThread__main__ + 1318
4 libsystem_pthread.dylib 0x00007fff8d2e4899 _pthread_body + 138
5 libsystem_pthread.dylib 0x00007fff8d2e472a _pthread_start + 137
6 libsystem_pthread.dylib 0x00007fff8d2e8fc9 thread_start + 13
It doesn't just affect the above method - it affects any code that uses NSTask
. I did some research and it was suggested that repairing permissions may fix the issue, but that's not very useful because I have no way of getting in contact with the users reporting these crashes. I am already placing the code in a try catch block - is there anything else I can do at my end to minimize or eliminate it?
I wrote the following function to wrap around NSTask
.
Code:
+ (BOOL)runTask:(NSString*)taskPath arguments:(NSArray*)args task:(NSTask**)taskObj
{
if (![[NSFileManager defaultManager] isExecutableFileAtPath:taskPath] || [[NSWorkspace sharedWorkspace] isFilePackageAtPath:taskPath]) {
NSLog(@"Error: %@ is not executable",taskPath);
return NO;
}
@try {
NSTask *task = [[NSTask alloc] init];
if (taskObj != NULL) *taskObj = task;
[task setLaunchPath:taskPath];
if (args) [task setArguments:args];
[task setStandardError:[NSFileHandle fileHandleWithNullDevice]];
[task setStandardOutput:[NSFileHandle fileHandleWithNullDevice]];
[task launch];
[task waitUntilExit];
taskObj = nil;
[task release];
return YES;
}
@catch (NSException *exc) {
NSLog(@"Exception running task %@: %@",taskPath,[exc reason]);
}
return NO;
}
If rebooting fixes the problem, then it seems that minimizing your file handles may help prevent this issue. But, I would still try to reproduce the issue locally, by creating a lot of file handles without closing them, so that you know for sure what is causing the crash.
I see that you are creating your file handle as you pass it as a parameter. This prevents you from controlling when that file handle is closed. I would instead keep a reference to the file handle, so that you can close it when it is no longer used:
NSFileHandle *errorFileHandle = [NSFileHandle fileHandleWithNullDevice];
[task setStandardError:errorFileHandle];
NSFileHandle *outputFileHandle = [NSFileHandle fileHandleWithNullDevice];
[task setStandardOutput:outputFileHandle];
...
//outputFileHandle is no longer used
[outputFileHandle close];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With