0

This is my first real Cocoa project. I wrote a function that takes a NSString as input, uses an NSTask to run an ADB command, and returns the terminal output to an NSString. The code builds fine, but when I press the button to run that function, the app freezes. When I force close, I see Thread 1: signal SIGTERM on the line data = [file readDataToEndOfFile];.

Function

NSString* runADBCommand(NSString *cmd)
{
    [[NSTask launchedTaskWithLaunchPath:adbPath
                              arguments:[NSArray arrayWithObjects: cmd, nil]]waitUntilExit];

    NSTask *adbDevices = [[NSTask alloc] init];
    adbDevices.launchPath = adbPath;
    NSString* devices = @"devices";
    adbDevices.arguments = @[devices];

    NSPipe *pipe;
    pipe = [NSPipe pipe];
    [adbDevices setStandardOutput:pipe];

    NSFileHandle *file;
    file = [pipe fileHandleForReading];

    NSData *data;
    data = [file readDataToEndOfFile];

    NSString *adbComOutput;
    adbComOutput = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    NSLog(@"\n\n%@", adbComOutput);
    return adbComOutput;
}

Call

- (void) getVersion:(id)sender
{
    runADBCommand(@"shell cat /system/build.prop | grep incremental");
}

I've been looking for references online, but am not sure what to look for. Any help is appreciated!

Thomas
  • 5,810
  • 7
  • 40
  • 48

1 Answers1

1

The signal SIGTERM message is a consequence of you force-quitting the process. That's the mechanism by which force-quit is accomplished: a POSIX signal, in particular SIGTERM, is delivered to the target process and that typically causes it to terminate.

Since the process is being debugged, the debugger intercepts the signal and tells you about it so that you can debug it. Of course, in this case, you're not interested in debugging the receipt of this signal. (By the way, you can just click the Stop button in Xcode's toolbar to stop the stuck process without this side effect. You could also click the Pause button to interrupt the program without terminating it to learn where it is stuck and investigate why.)

The real question is: why is your call to -readDataToEndOfFile blocking forever. The reason is simple, you never launched the task that would write output and then close the write end of the pipe. You never call [adbDevices launch]. Of course, you would need to do that before blocking waiting for its output.

Also, the runADBCommand() function as you posted it instantiates two tasks objects. The first line:

[[NSTask launchedTaskWithLaunchPath:adbPath
                          arguments:[NSArray arrayWithObjects: cmd, nil]]waitUntilExit];

creates and launches a task and waits for it to exit. The function then goes on to create a completely different task to run the devices command. I suspect this is just a remnant of experimentation. I just wanted to be sure you were aware of it.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • Thanks so much for this awesome explanation! I didn't even realize I left out the launch statement. I put `[adbDevices launch];` right after `file = [pipe fileHandleForReading];` and it works perfectly! – Thomas Jan 27 '15 at 18:30