Подтвердить что ты не робот

Ошибка Runtime.exec(): зависает без предоставления объекта Process

Использую ли я это:

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

или что:

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

Я получаю те же результаты: он часто зависает в вызове exec() или start(), независимо от того, что я пытался сделать! Нить с этим не может быть прервана с помощью Thread.interrupt()! Детский процесс определенно запущен, и если его убили, вернутся эти команды.

Эти вызовы могут потерпеть неудачу при первой попытке, поэтому НЕ МОЖЕТ ПРОЧИТАТЬ ИХ ВЫХОД! Я также могу использовать простую командную строку "su -c kill xxx", тот же результат!

EDIT: начата отладка файла java_lang_ProcessManager.cpp в проекте NDK с некоторыми журналами отладки! Итак, вот что я нашел до сих пор, после fork() родитель делает это:

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

Хотя дочерний процесс не должен блокироваться на нем: это то, что делает ребенок (, если он вообще запущен!):

    // 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);

Ребенок может потерпеть неудачу по двум воспроизводимым причинам: 1- дочерний код не работает, но родитель полагает, что это так! 2- дочерние блоки на       closeNonStandardFds (statusOut, androidSystemPropertiesFd);

В любом случае чтение (statusIn...) в родительском завершается в тупике! и дочерний процесс остается мертвым (и к нему нельзя получить доступ, pid неизвестно, нет объекта процесса)!

4b9b3361

Ответ 1

Эта проблема исправлена ​​в желе Bean (Android 4.1), но не в ICS (4.0.4), и я думаю, он никогда не будет исправлен в ICS.

Ответ 2

Выше решение не оказалось надежным в любом случае, вызывая больше проблем на некоторых устройствах!

Итак, я вернулся к стандартному .exec() и продолжал копать...

Посмотрев на дочерний код, который висит, я заметил, что дочерний процесс зависает, пытаясь закрыть все дескрипторы файлов, унаследованные от родительского (кроме того, что создано в вызове exec())!

Итак, я просматриваю весь код приложения для любого BufferedReader/Writer и подобных классов, чтобы убедиться, что они будут закрыты при вызове exec()!

Частота проблемы была значительно уменьшена и фактически никогда не возникала снова, когда я удалял последний открытый файловый дескриптор перед вызовом exec().

NB: Убедитесь, что SU-бинарный файл обновлен, он также может вызвать эту проблему!

Наслаждайтесь поиском;)

Ответ 3

Исправление ошибок в Bionic было зарегистрировано месяц назад, но оно по-прежнему не включено в Android 4.0.4.

Ответ 4

У меня такая же проблема на ICS (похоже, отлично работает на Android < 4). Вы нашли решение?

Простым обходным решением может быть вызов метода "exec" в выделенном потоке с тайм-соединением, чтобы эта ситуация могла быть "обнаружена" (да, я знаю, что это не очень элегантно...)