Createprocess и ошибка 0xc0000142

у меня есть следующий тестовый код:

#define CMDLINE ".\\dummyFolder\\dummyProc.exe op1 op2 op3"

int main(int argc, char **argv) {

STARTUPINFO info;
info.cb = sizeof(STARTUPINFO);
info.lpReserved = NULL;
info.cbReserved2 = 0;
info.lpReserved2 = NULL;

PROCESS_INFORMATION processInfo;

SECURITY_ATTRIBUTES procAttr;
procAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
procAttr.lpSecurityDescriptor = NULL;
procAttr.bInheritHandle = false;

SECURITY_ATTRIBUTES threadAttr;
procAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
procAttr.lpSecurityDescriptor = NULL;
procAttr.bInheritHandle = false;

bool handlersInheritable = true;

char cmdLine2[sizeof(CMDLINE)];
strcpy(cmdLine2, CMDLINE);

char AppName[sizeof(".\\dummyFolder\\dummyProc.exe")];
strcpy(AppName, ".\\dummyFolder\\dummyProc.exe");


if (CreateProcess(AppName, cmdLine2, &procAttr, &threadAttr,
        handlersInheritable, 0, NULL, NULL, &info, &processInfo)) {

    //::WaitForMultipleObjects(procQty, handlers, waitForAll, waitInterval);
    CloseHandle(processInfo.hProcess);
    CloseHandle(processInfo.hThread);
    CloseHandle(info.hStdError);
    CloseHandle(info.hStdInput);
    CloseHandle(info.hStdOutput);
} else {
    std::cout << "Returned: " << GetLastError() << std::endl;
}

std::cout << "Exiting main process" << std::endl;

return 0;
}

Это всего лишь тестовый код для создания процессов в windows. Проблема в том, что когда я запускаю "dummyProc.exe", я получаю ошибку 0xc0000142.

Процесс dummyProc.exe нормально запускается из командной строки, но не из кода.

Вот код dummyProc, если поможет:

int main(int argc, char **argv) {


std::cout << "Working!!!!" << std::endl << "Receivedi: " << std::endl;

for (int i = 0; i < argc; ++i)
    std::cout << argv[i] << std::endl;


return 0;
}

Итак, есть идеи?


person ExusTheOne    schedule 04.02.2012    source источник
comment
См. support.microsoft.com/kb/960266.   -  person Seth Carnegie    schedule 04.02.2012


Ответы (2)


Самое очевидное, что char cmdLine2[sizeof(CMDLINE)]; объявляет строку длиной, равной размеру указателя вашей машины. Вместо этого вам нужно использовать strlen(CMDLINE)+1. Аналогично для appName.

Обратите внимание, что первый параметр CreateProcess не обязательно должен быть доступным для записи. Просто передайте ему строковый литерал. Нет необходимости в переменной appName.

Что касается lpCommandLine, который должен быть доступен для записи, проще всего сделать это следующим образом:

char cmdline[] = "op1 op2 op3";

Это дает вам записываемый буфер. Обратите внимание, что вам не нужно повторять имя исполняемого файла.

Другая проблема заключается в том, что вы не инициализировали все параметры в CreateProcess. Например, структура STARTUPINFO имеет 19 полей, и вы инициализируете только 3. Вы должны инициализировать все свои структуры до 0, а затем заполнить все поля, которые вам нужны, чтобы они были ненулевыми. Нравится:

STARTUPINFO info = { 0 };

Сделайте это для всех структур, которые вы передаете.

Вы можете и должны передать NULL для параметров lpProcessAttributes и lpThreadAttributes.

person David Heffernan    schedule 04.02.2012

Этот ответ связан с другой причиной для 0xc0000142, размещенной здесь (хотя на этот вопрос был принят другой ответ), потому что на интертрубах очень мало полезной информации об этой ошибке, а также шокирующее отсутствие < em>любую полезную информацию по этому вопросу от Microsoft - и поэтому чей-то интернет-поиск может найти их здесь. (Ну, мой сделал.)

Итак: вы можете получить The application was unable to start correctly (0xc0000142) при запуске процесса, написанного на C++, где вы получаете доступ через нулевой указатель в конструкторе статического объекта. (В моем случае это было в инициализаторе конструктора статического объекта.)

Вашим намеком на это будет событие в журнале приложения (событие с идентификатором 1000, источник «Ошибка приложения»), в котором есть строки, подобные следующим:

Faulting module name: unknown, version: 0.0.0.0, time stamp: 0x00000000
Exception code: 0xc0000005
Fault offset: 0x0000000000000000

0xc0000005 — это, конечно, нарушение прав доступа, а смещение 0 (на самом деле все, что меньше 0x10000, — это ссылка через нулевой указатель.

Во всяком случае, удивительно (для меня) то, что оценка статики происходит до того, как отладчик сможет подключиться (!!), поэтому запуск его с набором ImageFileExecutionOptions или даже непосредственно в Visual Studio не позволяет вам отлаживать эту вещь. !!

(И тогда, конечно, вы не найдете 0xc0000142 ни в одной документации Microsoft. Молодцы, команда NT!)

person davidbak    schedule 19.03.2017