Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
355 views
in Technique[技术] by (71.8m points)

android - Runtime.exec() bug: hangs without providing a Process object

Whether I use this:

process = Runtime.getRuntime().exec("logcat -d time");

or that:

process = new ProcessBuilder()
              .command("logcat", "-d", "time")
              .redirectErrorStream(true)
              .start();

I get the same results: it often hangs within the exec() or start() call, no matter what I tried to do! The thread running this cannot even be interrupted with Thread.interrupt()! The child process is definitely started and if killed the above commands return.

These calls may fail on first attempt, so THERE IS NO WAY TO READ THEIR OUTPUT! I can also use a simple "su -c kill xxx" command line, same result!

EDIT: Started debugging the java_lang_ProcessManager.cpp file in an NDK project with some debugging logs! So here is what I found so far, after the fork() the parent does this:

int result;
int count = read(statusIn, &result, sizeof(int));            <- hangs there
close(statusIn);

Though the child process is not supposed to block on it: That's what the child does (if started at all!):

    // Make statusOut automatically close if execvp() succeeds.
    fcntl(statusOut, F_SETFD, FD_CLOEXEC);                      <- make the parent will not block

    // Close remaining unwanted open fds.
    closeNonStandardFds(statusOut, androidSystemPropertiesFd);  <- hangs here sometimes

    ...

    execvp(commands[0], commands);

    // If we got here, execvp() failed or the working dir was invalid.
    execFailed:
        int error = errno;
        write(statusOut, &error, sizeof(int));
        close(statusOut);
        exit(error);

The child can fail for 2 reproducible reasons: 1- child code is not running, but the parent believes it is! 2- child blocks on closeNonStandardFds(statusOut, androidSystemPropertiesFd);

In either case the read(statusIn...) in the parent ends in deadlock! and a child process is left dead (and cannot be accessed, pid unknown, no Process object)!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This problem is fixed in Jelly Bean (Android 4.1) but not in ICS (4.0.4) and I guess it will never be fixed in ICS.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...