Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Thema werden alle vorbereitenden Schritte aufgeführt, die vor dem Debuggen einer Dienstanwendung erforderlich sein können. Welche Schritte in Ihrem spezifischen Szenario erforderlich sind, hängt davon ab, welche Anfügeoption und Debugkonfiguration Sie ausgewählt haben. Eine Liste dieser Optionen finden Sie unter Auswählen der besten Methode zum Debuggen einer Dienstanwendung.
Jede der in diesem Thema beschriebenen Vorbereitungsschritte gibt die Bedingungen an, unter denen sie erforderlich ist. Diese Schritte können in beliebiger Reihenfolge ausgeführt werden.
Aktivieren des Debuggings des Initialisierungscodes
Wenn Sie beabsichtigen, die Dienstanwendung vom Anfang der Ausführung einschließlich des Initialisierungscodes zu debuggen, ist dieser vorbereitende Schritt erforderlich.
Suchen oder erstellen Sie den folgenden Registrierungsschlüssel, wobei ProgramName der Name der ausführbaren Datei der Dienstanwendung ist:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ProgramName
ProgramName- sollte die Dateinamenerweiterung enthalten, aber nicht den Pfad. Beispielsweise könnte ProgramName Myservice.exe oder Thisservice.dll sein.
Erstellen Sie unter diesem Registrierungsschlüssel einen Zeichenfolgendatenwert mit dem Titel Debugger. Der Wert dieser Zeichenfolge sollte auf den vollständigen Pfad und Dateinamen eines Debuggers festgelegt werden, der an die Dienstanwendung angefügt werden soll.
Wenn Sie beabsichtigen, lokal zu debuggen, verwenden Sie eine Zeichenfolge wie die folgenden:
c:\Debuggers\windbg.exe
Wählen Sie diese Option nicht aus, wenn Sie Windows Vista oder eine höhere Version von Windows ausführen.
Wenn Sie Remote-Debugging verwenden möchten, geben Sie „NTSD“ mit der Option -noio an. Dadurch wird NTSD ohne eigene Konsole ausgeführt, auf die nur über die Remoteverbindung zugegriffen werden kann. Zum Beispiel:
c:\Debuggers\ntsd.exe -server ServerTransport -noio -y SymbolPath
Wenn Ihre Debugsitzung beginnt, bevor Windows vollständig geladen ist, können Sie möglicherweise nicht über eine Remotefreigabe auf Symbole zugreifen. In diesem Fall müssen Sie lokale Symbole verwenden. ServerTransport- muss ein Transportprotokoll angeben, das vom Windows-Kernel implementiert wird, ohne mit einem Benutzermodusdienst, z. B. TCP oder NPIPE, interfacieren zu müssen. Informationen zur Syntax von ServerTransport finden Sie unter Aktivieren eines Debugservers.
Wenn Sie den Benutzermodusdebugger über einen Kernelmodusdebugger steuern möchten, geben Sie NTSD mit der Option -d an. Zum Beispiel:
c:\Debuggers\ntsd.exe -d -y SymbolPath
Wenn Sie diese Methode verwenden möchten und Ihre Benutzermodus-Symbole von einem Symbolserver abgerufen werden, sollten Sie diese Methode mit Remote-Debugging kombinieren. Geben Sie in diesem Fall „NTSD“ mit der Option -ddefer an. Wählen Sie ein Transportprotokoll aus, das vom Windows-Kernel implementiert wird, ohne mit einem Benutzermodusdienst wie TCP oder NPIPE zu interfacieren. Zum Beispiel:
c:\Debuggers\ntsd.exe -server ServerTransport -ddefer -y SymbolPath
Details finden Sie unter Steuern des Benutzermodusdebuggers über den Kerneldebugger .
Nach Abschluss dieser Registrierungsbearbeitung wird der Debugger gestartet, wenn ein Dienst mit diesem Namen gestartet oder neu gestartet wird.
Aktivieren der Dienstanwendung für die Unterbrechung des Debuggers
Wenn Sie möchten, dass die Dienstanwendung den Debugger unterbricht, wenn er abstürzt oder auf eine Ausnahme trifft, müssen Sie diesen vorbereitenden Schritt ausführen. Dieser Schritt ist auch erforderlich, wenn die Dienstanwendung in den Debugger einbrechen soll, indem Sie die DebugBreak--Funktion aufrufen.
Hinweis Wenn Sie das Debuggen des Initialisierungscodes aktiviert haben (der im Unterabschnitt "Aktivieren des Debuggings des Initialisierungscodes" beschriebene Schritt), sollten Sie diesen Schritt überspringen. Wenn das Debuggen von Initialisierungscode aktiviert ist, wird der Debugger beim Start an die Dienstanwendung angefügt. Auf diese Weise werden alle Abstürze, Ausnahmen und Aufrufe von DebugBreak an den Debugger weitergeleitet, ohne dass eine zusätzliche Vorbereitung erforderlich ist.
Dieser vorbereitende Schritt umfasst die Registrierung des ausgewählten Debuggers als Postmortem-Debugger. Dazu werden die Optionen -iae oder -iaec in der Befehlszeile des Debuggers verwendet. Wir empfehlen die folgenden Befehle. Wenn Sie diese ändern möchten, finden Sie Informationen zu den Syntaxdetails in Aktivieren des Postmortem-Debuggings.
Wenn Sie beabsichtigen, lokal zu debuggen, verwenden Sie einen Befehl wie den folgenden:
windbg -iae
Wählen Sie diese Option nicht aus, wenn Sie Windows Vista oder eine höhere Version von Windows ausführen.
Wenn Sie Remote-Debugging verwenden möchten, geben Sie „NTSD“ mit der Option -noio an. Dadurch wird NTSD ohne eigene Konsole ausgeführt, auf die nur über die Remoteverbindung zugegriffen werden kann. Um einen Postmortemdebugger mit dem Parameter „-server“ zu installieren, müssen Sie die Registrierung manuell bearbeiten. Details hierzu finden Sie unter Aktivieren des Postmortem-Debuggings. Der Wert für Debugger des Schlüssels AeDebug könnte beispielsweise wie folgt aussehen:
ntsd -server npipe:pipe=myproc%x -noio -p %ld -e %ld -g -y SymbolPath
In der Pipespezifikation wird das %x-Token durch die Prozess-ID des Prozesses ersetzt, der den Debugger startet. Dies stellt sicher, dass jeder Postmortemdebugger einen eindeutigen Pipenamen hat, wenn mehrere Prozesse einen Postmortemdebugger starten. Wenn Ihre Debugsitzung beginnt, bevor Windows vollständig geladen ist, können Sie möglicherweise nicht über eine Remotefreigabe auf Symbole zugreifen. In diesem Fall müssen Sie lokale Symbole verwenden. ServerTransport- muss ein Transportprotokoll angeben, das vom Windows-Kernel implementiert wird, ohne mit einem Benutzermodusdienst, z. B. TCP oder NPIPE, interfacieren zu müssen. Informationen zur Syntax von ServerTransport finden Sie unter Aktivieren eines Debugservers.
Wenn Sie den Benutzermodusdebugger über einen Kernelmodusdebugger steuern möchten, geben Sie NTSD mit der Option -d an. Zum Beispiel:
ntsd -iaec -d -y SymbolPath
Wenn Sie diese Methode auswählen und auf Benutzermodussymbole von einem Symbolserver zugreifen möchten, sollten Sie diese Methode mit Remotedebugging kombinieren. Geben Sie in diesem Fall „NTSD“ mit der Option -ddefer an. Wählen Sie ein Transportprotokoll aus, das vom Windows-Kernel implementiert wird, ohne mit einem Benutzermodusdienst wie TCP oder NPIPE zu interfacieren. Um einen Postmortem-Debugger zu installieren, der den Parameter -server enthält, müssen Sie die Registrierung manuell bearbeiten; für weitere Informationen siehe Aktivieren des Postmortem-Debuggings. Der Wert für Debugger des Schlüssels AeDebug könnte beispielsweise wie folgt aussehen:
ntsd -server npipe:pipe=myproc%x -ddefer -p %ld -e %ld -g -y SymbolPath
Details finden Sie unter Steuern des Benutzermodusdebuggers über den Kerneldebugger .
Wenn Sie einen dieser Befehle ausführen, wird der Postmortemdebugger registriert. Dieser Debugger wird gestartet, wenn jedes Benutzermodusprogramm, einschließlich einer Dienstanwendung, auf eine Ausnahme stößt oder eine DebugBreak--Funktion ausführt.
Anpassen des Timeouts für die Dienstanwendung
Wenn Sie beabsichtigen, den Debugger automatisch zu starten (entweder wenn der Dienst gestartet wird oder eine Ausnahme auftritt), ist dieser vorbereitende Schritt erforderlich.
Suchen Sie den folgenden Registrierungsschlüssel:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
Suchen Sie unter diesem Schlüssel nach einem DWORD-Datenwert mit dem Namen ServicesPipeTimeoutoder erstellen Sie diesen. Legen Sie diesen Eintrag auf die Zeit in Millisekunden fest, die der Dienst warten soll, bevor das Zeitlimit abläuft. Beispielsweise entspricht der Wert 60.000 einer Minute, während der Wert 86.400.000 24 Stunden entspricht. Wenn dieser Registrierungswert nicht festgelegt ist, beträgt das Standardtimeout etwa dreißig Sekunden.
Die Bedeutung dieses Werts ist, dass ein Timer gestartet wird, wenn jeder Dienst gestartet wird, und wenn der Timeout-Wert erreicht wird, wird jeder Debugger beendet, der dem Dienst zugeordnet ist. Daher sollte der von Ihnen ausgewählte Wert länger sein als die Gesamtdauer, die zwischen dem Starten des Diensts und dem Abschluss der Debugsitzung verstrichen ist.
Diese Einstellung gilt für jeden Dienst, der gestartet oder neu gestartet wird, nachdem die Registrierungsbearbeitung abgeschlossen ist. Wenn ein Dienst abstürzt oder hängt und diese Einstellung noch wirksam ist, wird das Problem von Windows nicht erkannt. Daher sollten Sie diese Einstellung nur während des Debuggens verwenden und den Registrierungsschlüssel nach Abschluss des Debuggings an den ursprünglichen Wert zurückgeben.
Isolieren des Diensts
Manchmal werden mehrere Dienste in einem einzigen Diensthostprozess (Svchost-Prozess) kombiniert. Wenn Sie einen solchen Dienst debuggen möchten, müssen Sie ihn zuerst in einen separaten Svchost-Prozess isolieren.
Es gibt drei Methoden, mit denen Sie einen Dienst isolieren können. Microsoft empfiehlt die Methode "Verschieben des Dienstes in eine eigene Gruppe", wie folgt. Die alternativen Methoden (Ändern des Diensttyps und Duplizieren der SvcHost-Binärdatei) können auf temporärer Basis für das Debuggen verwendet werden, da sie jedoch die Ausführung des Diensts ändern, sind sie nicht so zuverlässig wie die erste Methode.
Bevorzugte Methode: Verschieben des Dienstes in eine eigene Gruppe
Verwenden Sie das folgende Dienstkonfigurationstool (Sc.exe), wobei der Name des Diensts ServiceName ist:
sc qc ServiceName
Dadurch werden die aktuellen Konfigurationswerte für den Dienst angezeigt. Der relevante Wert ist BINARY_PATH_NAME, der die Befehlszeile angibt, die zum Starten des Dienststeuerungsprogramms verwendet wird. Da Ihr Dienst in diesem Szenario noch nicht isoliert ist, enthält diese Befehlszeile einen Verzeichnispfad, Svchost.exeund einige SvcHost-Parameter, einschließlich des -k Schalters, gefolgt von einem Gruppennamen. Es kann z. B. wie folgt aussehen:
%SystemRoot%\System32\svchost.exe -k LocalServiceNoNetwork
Denken Sie an diesen Pfad und den Gruppennamen; sie werden in den Schritten 5 und 6 verwendet.
Suchen Sie den folgenden Registrierungsschlüssel:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost
Erstellen Sie einen neuen REG_MULTI_SZ Wert mit einem eindeutigen Namen (z. B. TempGrp).
Legen Sie diesen neuen Wert auf den Namen des Diensts fest, den Sie isolieren möchten. Schließen Sie keine Verzeichnispfade oder Dateinamenerweiterungen ein. Beispielsweise können Sie den neuen Wert TempGrp auf MyService festlegen.
Erstellen Sie unter demselben Registrierungsschlüssel einen neuen Schlüssel mit demselben Namen, den Sie in Schritt 2 verwendet haben. Zum Beispiel:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\TempGrp
Jetzt enthält der SvcHost-Schlüssel einen Wert mit dem neuen Namen und hat auch einen untergeordneten Schlüssel mit diesem gleichen Namen.
Suchen Sie nach einem anderen Schlüssel, der dem SvcHost-Schlüssel untergeordnet ist, der denselben Namen wie die Gruppe aufweist, die Sie in Schritt 1 gefunden haben. Wenn ein solcher Schlüssel vorhanden ist, überprüfen Sie alle darin enthaltenen Werte, und erstellen Sie Duplikate davon im neuen Schlüssel, den Sie in Schritt 4 erstellt haben.
Beispielsweise kann der alte Schlüssel wie folgt benannt werden:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\LocalServiceNoNetwork
Dies kann beispielsweise Werte wie CoInitializeSecurityParam, AuthenticationCapabilities und andere Werte enthalten. Sie würden zum neu erstellten Schlüssel wechseln:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\TempGrp
und erstellen Sie Darin Werte, die in Name, Typ und Daten mit denen im alten Schlüssel identisch sind.
Wenn der alte Schlüssel nicht vorhanden ist, müssen Sie keinen neuen Schlüssel erstellen.
Verwenden Sie den folgenden Dienstkonfigurationstoolbefehl, um den Pfad in Schritt 1 zu ändern:
sc config ServiceName binPath= "RevisedPath"
In diesem Befehl ist ServiceName der Name des Diensts, und RevisedPath ist der neue Wert, den Sie für BINARY_PATH_NAME bereitstellen. Verwenden Sie für RevisedPathgenau den Pfad wie der in Schritt 1 angezeigte, einschließlich aller Optionen in dieser Zeile, wobei nur eine Änderung vorgenommen wird: Ersetzen Sie den Parameter nach dem -k Schalter durch den Namen des neuen Registrierungswerts, den Sie in Schritt 2 erstellt haben. Schließen Sie RevisedPath in Anführungszeichen ein. Das Leerzeichen nach dem Gleichheitszeichen ist erforderlich.
Ihr Befehl könnte z. B. wie folgt aussehen:
sc config MyService binPath= "%SystemRoot%\System32\svchost.exe -k TempGrp"
Sie können den Befehl sc qc erneut verwenden, um die vorgenommene Änderung zu überprüfen.
Diese Einstellungen werden wirksam, wenn der Dienst das nächste Mal gestartet wird. Um die Auswirkungen des alten Diensts zu löschen, empfehlen wir, Windows neu zu starten, anstatt nur den Dienst neu zu starten.
Nachdem Sie das Debuggen abgeschlossen haben, und falls Sie diesen Dienst zum gemeinsamen Dienstanbieter zurückgeben möchten, verwenden Sie den Befehl sc config erneut, um den ursprünglichen Wert des binären Pfads wiederherzustellen und löschen Sie die neuen Registrierungsschlüssel und -werte, die Sie erstellt haben.
Alternative Methode: Ändern des Diensttyps
Verwenden Sie das folgende Dienstkonfigurationstool (Sc.exe), wobei der Name des Diensts ServiceName ist:
sc config ServiceName type= own
Das Leerzeichen nach dem Gleichheitszeichen ist erforderlich.
Starten Sie den Dienst neu, indem Sie die folgenden Befehle verwenden:
net stop ServiceName net start ServiceName
Diese Alternative ist nicht die empfohlene Methode, da sie das Verhalten des Diensts ändern kann. Wenn Sie diese Methode verwenden, verwenden Sie den folgenden Befehl, um zum normalen Verhalten zurückzukehren, nachdem Sie das Debuggen abgeschlossen haben:
sc config ServiceName type= share
Alternative Methode: Duplizieren der SvcHost-Binärdatei
Die Svchost.exe ausführbare Datei befindet sich im System32-Verzeichnis von Windows. Erstellen Sie eine Kopie dieser Datei, nennen Sie sie svhost2.exe, und platzieren Sie sie auch im System32-Verzeichnis.
Verwenden Sie das folgende Dienstkonfigurationstool (Sc.exe), wobei der Name des Diensts ServiceName ist:
sc qc ServiceName
Mit diesem Befehl werden die aktuellen Konfigurationswerte für den Dienst angezeigt. Der relevante Wert ist BINARY_PATH_NAME, der die Befehlszeile angibt, die zum Starten des Dienststeuerungsprogramms verwendet wird. In diesem Szenario, da Ihr Dienst noch nicht isoliert ist, enthält diese Befehlszeile einen Verzeichnispfad, Svchost.exeund wahrscheinlich einige SvcHost-Parameter. Es kann z. B. wie folgt aussehen:
%SystemRoot%\System32\svchost.exe -k LocalServiceNoNetwork
Um diesen Pfad zu überarbeiten, geben Sie den folgenden Befehl aus:
sc config ServiceName binPath= "RevisedPath"
In diesem Befehl ist ServiceName der Name des Diensts, und RevisedPath ist der neue Wert, den Sie für BINARY_PATH_NAME bereitstellen. Verwenden Sie für RevisedPathden genauen Pfad wie den in Schritt 2 angezeigten Pfad, einschließlich aller Optionen, die in dieser Zeile angezeigt werden, mit nur einer Änderung: Ersetzen Sie Svchost.exe durch Svchost2.exe. Schließen Sie RevisedPath in Anführungszeichen ein. Das Leerzeichen nach dem Gleichheitszeichen ist erforderlich.
Ihr Befehl könnte z. B. wie folgt aussehen:
sc config MyService binPath= "%SystemRoot%\System32\svchost2.exe -k LocalServiceNoNetwork"
Sie können den Befehl sc qc erneut verwenden, um die vorgenommene Änderung zu überprüfen.
Starten Sie den Dienst mit den folgenden Befehlen neu:
net stop ServiceName net start ServiceName
Diese Alternative ist nicht die empfohlene Methode, da sie das Verhalten des Diensts ändern kann. Wenn Sie diese Methode verwenden, verwenden Sie den Befehl sc config, um den Pfad zurück zum ursprünglichen Wert zu ändern, nachdem Sie das Debuggen abgeschlossen haben.