Runtime.exec()bug:挂起而不提供Process对象

3c7*_*c71 18 android process exec

我是否用这个:

process = Runtime.getRuntime().exec("logcat -d time");
Run Code Online (Sandbox Code Playgroud)

或者那个:

process = new ProcessBuilder()
              .command("logcat", "-d", "time")
              .redirectErrorStream(true)
              .start();
Run Code Online (Sandbox Code Playgroud)

我得到了相同的结果:它经常挂在exec()或start()调用中,无论我试图做什么!运行它的线程甚至不能被Thread.interrupt()中断!子进程肯定已启动,如果被杀死,则返回上述命令.

这些调用可能在第一次尝试时失败,所以没有办法阅读他们的输出!我也可以用一个简单的"su -c kill xxx"命令行,结果相同!

编辑:开始使用一些调试日志调试NDK项目中的java_lang_ProcessManager.cpp文件!所以这是我到目前为止找到的,在fork()之后父进程执行此操作:

int result;
int count = read(statusIn, &result, sizeof(int));            <- hangs there
close(statusIn);
Run Code Online (Sandbox Code Playgroud)

虽然子进程不应该阻止它:这就是孩子所做的事情(如果开始的话!):

    // 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);
Run Code Online (Sandbox Code Playgroud)

孩子可能会因为两个可重复的原因而失败:1-子代码没有运行,但父母认为它是!closeNonStandardFds上的2个子块(statusOut,androidSystemPropertiesFd);

在任何一种情况下,父级中的read(statusIn ...)都以死锁结束!并且子进程被遗忘(无法访问,pid未知,没有Process对象)!

chr*_*lri 6

这个问题在Jelly Bean(Android 4.1)中修复,但在ICS(4.0.4)中没有修复,我想它永远不会在ICS中修复.


小智 0

我在 ICS 上也遇到同样的问题(似乎在 Android < 4 上工作正常)。你找到解决办法了吗?

一个简单的解决方法可能是在带有超时连接的专用线程中调用“exec”方法,以便可以“检测到”这种情况(是的,我知道这不是很优雅......)