PRB: Untergeordnete Inherits unbeabsichtigtes Handles während CreateProcess-Aufruf

Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.

Den englischen Originalartikel können Sie über folgenden Link abrufen: 315939
Problembeschreibung
Beim Erstellen eines untergeordneten Prozesses rufen Sie mithilfe der CreateProcess -Funktion in einer Multithreadumgebung auf, das untergeordnete Element kann Handles, die nicht geerbt werden, erben.
Ursache
Dieses Verhalten kann auftreten, wenn zwei Threads gleichzeitig untergeordnete Prozesse erstellen und die STABW Handles über Pipes leiten. In diesem Szenario besteht eine Racebedingung während der Erstellung der Pipes und Prozesse, in denen es möglich, für ein Kind zum Erben von Dateihandles, die für die anderen untergeordneten vorgesehen ist. Ein Thread erstellt die Pipes und während der Thread ist der Erstellung des Prozesses, ist der andere Thread auch das einen untergeordneten Prozess erstellen. Alle Handles, die in der Anwendung während der CreateProcess -Aufruf vererbbare werden an den untergeordneten Prozess über dupliziert.
Lösung
Binden Sie, um dieses Problem zu umgehen, den Erstellung von untergeordneten Code in einen kritischen Abschnitt. Dadurch werden alle versehentliche Vererbung. Erstellen Sie für diese Methode funktioniert die Pipes als noninheritable, indem Sie die Sicherheitsbeschreibung auf NULL. Legen Sie dann das Ende der Pipe, die die untergeordneten, als vererbbar erben mithilfe des SetHandleInformation -Funktionsaufrufs, wie im folgenden Beispielcode gezeigt werden sollen:
CRITICAL_SECTION    cs;HANDLE              hReadIn, hWriteIn;HANDLE              hReadOut, hWriteOut;HANDLE              hReadErr, hWriteErr;InitializeCriticalSection(&cs);EnterCriticalSection(&cs);if ( !CreatePipe(&hReadIn, &hWriteIn, NULL, 0) ){    // an error occurred}if ( !CreatePipe(&hReadOut, &hWriteOut, NULL, 0) ){    // an error occurred}if ( !CreatePipe(&hReadErr, &hWriteErr, NULL, 0) ){    // an error occurred}if ( !SetHandleInformation(hReadIn, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT) ){    // an error occurred}if ( !SetHandleInformation(hWriteOut, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT) ){    // an error occurred}if ( !SetHandleInformation(hWriteErr, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT) ){    // an error occurred}STARTUP_INFO        si;PROCESS_INFORMATION pi;si.cb = sizeof(si);si.dwFlags = STARTF_USESTDHANDLES;si.hStdInput = hReadIn;si.hStdOutput = hWriteOut;si.hStdError = hWriteErr;if ( !CreateProcess( "child.exe",                     NULL,                     NULL, NULL,                     TRUE,                     NORMAL_PRIORITY_CLASS,                     lpEnvironment,                     &si, &pi) ){    // an error occurred}CloseHandle(hReadIn);CloseHandle(hWriteOut);CloseHandle(hWriteErr);LeaveCriticalSection(&cs);				
Hinweis, dass die vorherige Lösung nicht ohne Kosten stammen. Die Erstellung von kritischen Abschnitten im Code ist manchmal unübersichtlich und zu einem Preis Leistungsminderung kommt. Es ist eine andere Problemumgehung für dieses Problem und erfordert die Erstellung einer intermediate Anwendung, starten Sie das untergeordnete Element. Diese Lösung hat jedoch den Nachteil. Der Hauptnachteil dieser Methode ist, dass das übergeordnete Element die Benutzerfreundlichkeit im Grunde verliert mit der er die untergeordneten Prozess-ID erhält Wenn das übergeordnete Element die Prozess-ID benötigt, muss der intermediate Prozess es wieder irgendwie übergeben.

Durch Verwendung dieser Methode intermediate Anwendung vermeiden Sie eine versehentliche Vererbung auf Windows, um die Arbeit für Sie tun. Alle versehentlich geerbte Handles im intermediate-Prozess werden definitiv nicht über für die untergeordnete dupliziert werden. Dadurch ist gewährleistet, wenn Sie falsch für den bInheritHandles -Parameter im Aufruf von CreateProcess in die intermediate Anwendung angeben. Die Pipe-Handles werden noch dupliziert werden, weil Windows immer die Ziehpunkte STD duplizieren wird, auch wenn die bInheritHandles auf FALSE festgelegt ist.

Übergeordnete Anwendung

HANDLE              hReadIn, hWriteIn;HANDLE              hReadOut, hWriteOut;HANDLE              hReadErr, hWriteErr;if ( !CreatePipe(&hReadIn, &hWriteIn, NULL, 0) ){    // an error occurred}if ( !CreatePipe(&hReadOut, &hWriteOut, NULL, 0) ){    // an error occurred}if ( !CreatePipe(&hReadErr, &hWriteErr, NULL, 0) ){    // an error occurred}STARTUP_INFO        si;PROCESS_INFORMATION pi;si.cb = sizeof(si);si.dwFlags = STARTF_USESTDHANDLES;si.hStdInput = hReadIn;si.hStdOutput = hWriteOut;si.hStdError = hWriteErr;if ( !CreateProcess( "Intermediate.exe",                     NULL,                     NULL, NULL,                     TRUE,                     NORMAL_PRIORITY_CLASS,                     lpEnvironment,                     &si, &pi) ){    // an error occurred}CloseHandle(hReadIn);CloseHandle(hWriteOut);CloseHandle(hWriteErr);				

Intermediate-Anwendung

STARTUP_INFO        si;PROCESS_INFORMATION pi;si.cb = sizeof(si);if ( !CreateProcess( "child.exe",                     NULL,                     NULL, NULL,                     FALSE,                     NORMAL_PRIORITY_CLASS,                     lpEnvironment,                     &si, &pi) ){    // an error occurred}				

Warnung: Dieser Artikel wurde automatisch übersetzt.

Eigenschaften

Artikelnummer: 315939 – Letzte Überarbeitung: 11/21/2006 15:37:38 – Revision: 4.1

Microsoft Win32 Application Programming Interface

  • kbmt kbapi kbkernbase kbprb kbthread KB315939 KbMtde
Feedback