Android, CMDTool, перенаправление stdout, «Фатальный сигнал 11 (SIGSEGV)»

Использование регистра

Инструмент командной строки Android C ++ запускает «/ system / bin / getprop» и перенаправляет его стандартный вывод в сокет

проблема

Запуск getprop завершается неудачно с «F / libc (20694): фатальный сигнал 11 (SIGSEGV), код 1, адрес ошибки 0x0 в tid 20694 (getprop)», код & Ниже приведен фрагмент журнала.

Почему я получаю SIGSEGV? Почему разветвленный процесс терпит неудачу?

Реализация

HRESULT ServiceCore::CreateProcessAndRedirectStdout(IN char* pCmd, IN char** args, OUT SOCKET& stdoutstream) {
HRESULT hr      = S_OK;
int     fds[2]  = { 0 };
pid_t   pid     = 0;
stdoutstream = 0;
if (SOCKET_ERROR == socketpair(PF_UNIX, SOCK_STREAM, 0, fds))
goto ErrExit;
stdoutstream = fds[1];
if((pid = fork()) < 0)
goto ErrExit;
if (pid == 0) {
// The newly created process
__android_log_print(ANDROID_LOG_INFO, "ServiceCore", "CreateProcessAndRedirectStdout>> '%s' started", pCmd);
int newfd = dup2(fds[0], STDOUT_FILENO);
__android_log_print(ANDROID_LOG_INFO, "ServiceCore", "CreateProcessAndRedirectStdout>> '%s' newfd:%d, oldfd:%d", pCmd, newfd, fds[0]);
_ASSERT(newfd == STDOUT_FILENO);

close(fds[0]);
close(fds[1]);
execvp(pCmd, args);
__android_log_print(ANDROID_LOG_INFO, "ServiceCore", "CreateProcessAndRedirectStdout>> '%s' FAILED", pCmd);
exit(1);
}
__android_log_print(ANDROID_LOG_INFO, "ServiceCore", "CreateProcessAndRedirectStdout>> '%s(%d)' Created", pCmd, pid);
return S_OK;
ErrExit:
if (0 != pid)
kill(pid, SIGTERM);
close(fds[0]);
close(fds[1]);
stdoutstream = 0;
return hr;
}

...
char* args[] = { 0 };
SOCKET soc;
if (SUCCEEDED(hr = CreateProcessAndRedirectStdout("/system/bin/getprop", args, soc))) {
errno = 0;
__android_log_print(ANDROID_LOG_INFO, "ServiceCore", "SendConfig>> Reading props");
char pTmp[256000];
int iRet = read(soc, pTmp, sizeof(pTmp));// Read the first few lines
}

...

LogCat

I/ServiceCore(20689): CreateProcessAndRedirectStdout>> '/system/bin/getprop(20694)' Created

I/ServiceCore(20689): SendConfig>> Reading props

I/ServiceCore(20694): CreateProcessAndRedirectStdout>> '/system/bin/getprop' started

I/ServiceCore(20694): CreateProcessAndRedirectStdout>> '/system/bin/getprop' newfd:1, oldfd:10

F/libc    (20694): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 20694 (getprop)

1

Решение

Вы неправильно используете execvp () getprop не написано для обработки. Цитировать со страницы руководства OSX / BSD (но по сути общей) для execvp ()

Функции execv (), execvp () и execvP () предоставляют массив указателей на строки с нулевым символом в конце, которые представляют список доступных аргументов
к новой программе. Первый аргумент, по соглашению, должен указывать на
имя файла, связанное с исполняемым файлом. Массив
указатели должны заканчиваться нулевым указателем.

Вы нарушаете это соглашение, передавая массив из одного элемента NULL, когда Вы должны передать имя программы в качестве первого элемента, за которым следует завершающий элемент NULL.

Это устанавливает getprop до провала, поскольку он рассматривает возможность иметь только один аргумент (сам), и в этом случае он покажет все.

    if (argc == 1) {
list_properties();

Но если у него нет 1 аргумента, это предполагает он должен иметь два или более, и пытается отменить ссылку на второй, который должен быть названием собственности, которую вы хотите получить.

    property_get(argv[1], value, default_value);

Передача недопустимого и вероятного нулевого указателя вместо имени свойства в property_get () в конечном итоге завершается неудачно глубоко внутри bionic libc, вероятно, там, где реализация __system_property_find () вызывает strlen ().

Если бы вы исследовали трассировку стека, как предложил fadden, вы, вероятно, увидите адрес в libc, вероятно, strlen ().

1

Другие решения