Problems with NSTask in OS X 10.6 Snow Leopard

Has anyone else seen or heard of any issues with NSTask in 10.6?

This code worked well yesterday and doesn't work today.

NSTask *task = [converter task];
[task waitUntilExit];
NSLog(@"Task did complete");


The task does what it was supposed to do (I checked the output and that's fine), but the program will wait indefinitely on the method waitUntilExit

. I have several unit tests that use similar code, they all passed earlier, but as of yesterday, they no longer work.


source to share

5 answers

You need to add the following magic line:

[task setStandardInput:[NSPipe pipe]];




(1) Do you handle the exit from the task in any way? If so, output buffering may block if you don't read and process data along the way.

(2) Does your task wait for EOL on stdin before exiting? If so, you'll want to grab stdin and explicitly close it.

As Peter said, check ps to see if your task is still working. If so, use sample

to try it out to figure out what's wrong.



I may have noticed a problem with some of my 10.6 code that sounds suspiciously like your problem.

I needed to get some network information (mostly BGP and AS related) in a completely asynchronous manner. The ideal solution for me is to send ad hoc queries for the DNS TXT record to a public DNS server, but the Cocoa / Core Foundation does not provide an API to do such odd ball DNS queries. Another way is to use shell% whois -h IP 'SPECIAL REQUEST'

and simply parse the relevant information from the output. It was something that I could get up and running for hours and then go back and deliver a real solution. Very hackish, but terribly much faster than 1) finding a suitable asynchronous DNS library and 2) getting the speed on your API and possibly writing a wrapper for it.

So, I created a class that drops the background thread and then NSTask

to start the request whois

. The background thread sits in a loop NSRunLoop

to process the results, but checks every ~ 1 / 10th of a second to see if the default is dead NSTask

, or if [NSThread isCanceled]

, etc. It also registers for itself NSApplicationWillTerminateNotification

so that it can do a proper cleanup if the application leaves.

Okay, from 10.6 ... I couldn't leave "fast" anymore. At 10.5, all glass is smooth and the application closes instantly, at least perceptually. In section 10.6, shutting down the application will freeze. Debugging showed everything was hanging up trying to clear the lingering whois NSTask

s. Since none of the information I receive in this way is critical to the functionality of the applications (it is superfluous, nice to know any information), I just unlearned and stopped trying to get information as a solution to fill the gaps.

Quick transfers while debugging the issue showed that the main application was blocking the attempt to get instances NSLock

. The interesting thing is that if I just leave this alone, the app will eventually exit fine - from 10-20 seconds to minutes. Something changed between 10.5 and 10.6, which results in the code being squared in a block [NSLock lock] ... [NSLock unlock]

to "take a long time". I have yet to track down where this is happening (although not a priority yet) .... but one one of those things is to complete the background NSTask

if it is still running, and "waits for it to complete" before it can safely get rid of things like NSPipe


DUP : This could be a trick answer ... my first one seems to have disappeared in any of them?



Check ps, top or Activity Monitor. Make sure your process is complete.



Not sure if this helps, but you can try waiting on a separate thread:

[NSThread detachNewThreadSelector: @selector(foo) toTarget: self withObject: task];


- (void) foo: (NSTask *) task {
  [task launch];
  [task waitUntilExit];


I had a problem where I didn't receive the NSNotification when the task finished and this fixed it. Apparently there are some bugs in the NSTask implementation under 10.6 ...



All Articles