Fallstudie: Problembehandlung für ein unbekanntes USB-Gerät mithilfe von ETW und Netmon
Dieses Thema enthält ein Beispiel für die Verwendung von USB ETW und Netmon zur Problembehandlung eines USB-Geräts, das Windows nicht erkennt.
In diesem Beispiel haben wir ein Gerät angeschlossen, das als unbekanntes Gerät in Geräte-Manager und anderen Teilen der Benutzeroberfläche angezeigt wurde. Die Hardware-ID lautete "USB\UNKNOWN". Zur weiteren Diagnose haben wir das Gerät getrennt, eine ETW-Ablaufverfolgung gestartet und das Gerät wieder eingesteckt. Nachdem das Gerät als unbekanntes Gerät angezeigt wurde, wurde die Ablaufverfolgung beendet.
Informationen zum Problem mit dem unbekannten Gerät
Um ein unbekanntes USB-Geräteproblem zu debuggen, hilft es zu verstehen, was der USB-Treiberstapel tut, um ein Gerät aufzulisten, wenn ein Benutzer es an das System anbindet. Informationen zur USB-Enumeration finden Sie im Blogbeitrag Wie zählt ein USB-Stapel ein Gerät auf?
Wenn der USB-Treiberstapel ein Gerät in der Regel nicht aufzählen kann, meldet der Hubtreiber weiterhin die Ankunft des Geräts an Windows, und das USB-Gerät wird in Geräte-Manager als unbekanntes Gerät gekennzeichnet. Das Gerät verfügt über die Geräte-ID "USB\VID_0000&PID_0000" und die Hardware-ID und die kompatible ID "USB\UNKNOWN". Die folgenden Ereignisse führen dazu, dass der USB-Hubtreiber ein USB-Gerät als unbekanntes Gerät aufzählt:
- Bei einer Anforderung zur Portzurücksetzung ist während der Enumeration ein Timeout aufgetreten.
- Fehler bei der Anforderung "Adresse festlegen" für das USB-Gerät.
- Fehler bei der Anforderung für den Gerätedeskriptor des USB-Geräts.
- Der USB-Gerätedeskriptor war falsch formatiert und konnte nicht überprüft werden.
- Fehler bei der Anforderung für den Konfigurationsdeskriptor.
- Der USB-Konfigurationsdeskriptor war falsch formatiert und konnte nicht überprüft werden.
In Windows 7 werden unbekannte Geräte, bei denen die Enumeration fehlschlägt, in Geräte-Manager mit dem Fehlercode 43 gekennzeichnet.
Wenn ein Gerät in Geräte-Manager mit dem Fehlercode 28 gekennzeichnet ist, wurde das Gerät erfolgreich aufgezählt, ist aber immer noch ein unbekanntes Gerät. Dieser Fehlercode gibt an, dass das Gerät während der Enumeration keine Produkt-ID-Zeichenfolge bereitgestellt hat und Windows keine übereinstimmende INF für das Gerät zum Installieren eines Treibers finden konnte.
Starten der Ereignisablaufverfolgungsanalyse
Da es sich um einen Gerätefehler handelt, wird empfohlen, Netmon mit dem USB-Parser zu verwenden, um die Protokolldatei zu analysieren.
So zeigen Sie das Ereignisablaufverfolgungsprotokoll an
Führen Sie Netmon aus, klicken Sie auf Datei –> Öffnen –> Erfassen, und wählen Sie dann die Datei aus.
Wählen Sie im Bereich Framezusammenfassung das erste Ereignis aus, das die Beschreibung SystemTrace enthält. Diese Abbildung zeigt, wie der Bildschirm aussieht, wenn Sie das erste Ereignis auswählen.
Klicken Sie zum Anpassen der von Netmon angezeigten Spalten mit der rechten Maustaste auf einen Spaltennamen, und wählen Sie Spalten auswählen aus.
Das erste Ereignis, das als Typ SystemTrace identifiziert wird, enthält allgemeine Informationen zum Protokoll. Sie können die Informationsstruktur im Bereich Framedetails erweitern, um Informationen wie die Anzahl der verlorenen Ereignisse und die Startzeit der Ablaufverfolgung anzuzeigen.
USB-Gerätezusammenfassungsereignisse
Ereignis 2 ist das erste USB-Ereignis im Protokoll. Dies und mehrere nachfolgende Ereignisse beschreiben die USB-Hostcontroller, Hubs und Geräte, die beim Start der Ablaufverfolgung mit dem System verbunden waren. Wir können diese Gruppe von Ereignissen als Gerätezusammenfassungsereignisse oder einfach als Zusammenfassungsereignisse bezeichnen. Wie beim ersten Ereignis beschreiben die Zusammenfassungsereignisse nicht die Treiberaktivität. Zusammenfassungsereignisse zeichnen den Zustand der Geräte zu Beginn einer Protokollierungssitzung auf. Andere Ereignisse stellen ereignisse im Bus, Interaktionen mit Clienttreibern oder dem System oder Änderungen des internen Zustands dar.
Der USB-Hub und der USB-Porttreiber protokollieren zusammenfassungsereignisse. Der Treiber, der ein Ereignis protokolliert hat, wird in der Spalte Protokollname identifiziert. Beispielsweise weist ein Ereignis, das vom USB-Porttreiber protokolliert wird, den USBPort_MicrosoftWindowsUSBPORT Protokollnamen auf. Eine USB-Ereignisablaufverfolgung enthält in der Regel eine Sequenz von Portzusammenfassungsereignissen, gefolgt von einer Sequenz von Hubzusammenfassungsereignissen. Viele der USB-Port- und USB-Hub-Zusammenfassungsereignisse enthalten die Wörter "Information" oder "Attributes" in ihrer Beschreibung.
Wie können Sie das Ende der Zusammenfassungsereignisse ermitteln? Wenn das Zeitstempelmuster unter den USB-Hubereignissen am Anfang des Protokolls erheblich unterbrochen wird, ist diese Unterbrechung wahrscheinlich das Ende der Gerätezusammenfassung. Andernfalls ist das erste USB-Portereignis nach einem USB-Hubereignis wahrscheinlich das erste ereignis, das keine Zusammenfassung ist. Abbildung 3 auf der folgenden Seite zeigt das erste nicht zusammenfassende Ereignis in dieser Beispielablaufverfolgung.
In diesem Beispiel war das gerät von Interesse nicht mit dem System verbunden, als wir die Ablaufverfolgung gestartet haben, sodass Sie die Gerätezusammenfassungsereignisse vorerst überspringen können.
Ereignisbeschreibung und Datennutzlast
Im Beispielprotokoll ist das erste Ereignis nach den Gerätezusammenfassungsereignissen ein USB Hub Wait Wake IRP Completed-Ereignis. Wir haben ein Gerät angeschlossen, und ein Hostcontroller oder Hub wird als Reaktion darauf aktiviert. Um zu bestimmen, welche Komponente aktiviert wird, sehen Sie sich die Daten des Ereignisses an. Die Daten befinden sich im Bereich Framedetails, der in einer Strukturstruktur in etwa der folgenden Form angezeigt wird:
Frame information
ETW event header information
ETW event descriptor (Constant information about the event ID such
as error level)
Event payload (Data logged at the time of the event)
Name of a USB-specific structure
Structure members and their values (Types: numbers, strings,
or arrays)
...
Erweitern Sie die Nutzlastdaten für das USB Hub Wait Wake IRP Completed-Ereignis, und Sie sehen eine ETW-Struktur mit dem Namen fid_USBHUB_Hub. Der Name der -Struktur besteht aus den folgenden Komponenten:
Begriff | BESCHREIBUNG |
---|---|
Fid_ | Ein typisches Präfix für eine USB-ETW-Struktur. |
USBHUB_ | Ein Hinweis darauf, dass der USB-Hubtreiber das Ereignis protokolliert hat. |
Der Rest der Zeichenfolge | Der Name des Objekts, das in den Daten der Struktur beschrieben wird. Bei diesem Ereignis handelt es sich um ein Hub-Objekt. |
Der USB-Hubtreiber verwendet die fid_USBHUB_Hub-Struktur , um einen USB-Hub zu beschreiben. Ereignisse, die diese Hubstruktur in ihrer Datennutzlast enthalten, beziehen sich auf einen Hub, und wir können den spezifischen Hub anhand des Inhalts der -Struktur identifizieren. Abbildung 4 zeigt den Bereich Framedetails mit erweiterter fid_USBHUB_Hub-Struktur , um die zugehörigen Felder anzuzeigen.
Die Hubstruktur ähnelt zwei anderen Strukturen, die häufig in USB-ETW-Ereignissen vorkommen: fid_USBHUB_Device und fid_USBPORT_Device. Die folgenden wichtigen Felder sind für alle drei Strukturen gemeinsam:
Feld | BESCHREIBUNG |
---|---|
fid_idVendor | Die USB-Anbieter-ID (VID) des Geräts |
fid_idProduct | Die USB-Produkt-ID (PID) des Geräts |
fid_PortPath | Die Liste der 1-basierten Hubportnummern, über die ein USB-Gerät angeschlossen ist. Die Anzahl der Portnummern in der Liste ist im Feld PortPathDepth enthalten. Für die Stammhubgeräte sind alle Nullen in dieser Liste enthalten. Für ein USB-Gerät, das direkt mit einem Stammhubport verbunden ist, ist der Wert in PortPath[0] die Stammhubportnummer des Ports, an den das Gerät angeschlossen ist. |
Bei einem USB-Gerät, das über einen oder mehrere zusätzliche USB-Hubs verbunden ist, beginnt die Liste der Hubportnummern mit dem Stammhubport und wird mit den zusätzlichen Hubs fortgesetzt (in der Reihenfolge der Entfernung vom Stammhub). Ignorieren Sie alle Nullen. Beispiel:
Beispielwert | BESCHREIBUNG |
---|---|
[0, 0, 0, 0, 0, 0] | Das Ereignis bezieht sich auf einen Stammhub (einen Port auf dem PC, der direkt von einem USB-Hostcontroller gesteuert wird). |
[3, 0, 0, 0, 0, 0] | Das Ereignis bezieht sich auf einen Hub oder ein Gerät, das an die Portnummer 3 eines Stammhubs angeschlossen ist. |
[3, 1, 0, 0, 0, 0] | Ein Hub ist an den Port 3 eines Stammhubs angeschlossen. Das Ereignis bezieht sich auf einen Hub oder ein Gerät, das an den Port 1 dieses externen Hubs angeschlossen ist. |
Sie sollten die Portpfade aller relevanten Geräte überwachen. Wenn ein Gerät aufgezählt wird, werden VID und PID unbekannt und als 0 protokolliert. Die VID und PID werden während einiger niedriger Geräteanforderungen wie Zurücksetzen und Anhalten nicht angezeigt. Diese Anforderungen werden an den Hub gesendet, an den das Gerät angeschlossen ist.
In unserem Beispielprotokoll weist das Wait Wake-Abschlussereignis einen Portpfad mit sechs Nullen auf. Das -Ereignis gibt eine Wait Wake-Aktion auf einem Stammhub an. Dies ist aufgrund unserer Aktionen logisch: Wir haben das Gerät an einen Stammhubport angeschlossen, damit der Stammhub aktiviert wird.
USB Netmon-Filter
Sie können jedes Ereignis in einem Protokoll in chronologischer Reihenfolge untersuchen, wenn Sie Zeit haben. Selbst mit Erfahrung ist es schwierig, die wichtigen Ereignisse schnell zu identifizieren, indem die Liste der Ereignisbeschreibungen gescannt wird. Um die Ursache des unbekannten Geräts schneller zu ermitteln, können Sie die Netmon-Filterfunktion verwenden.
Der USB-Fehlerfilter
Klicken Sie zum Aktivieren des USB-Fehlerfilters in Netmon auf Filter –> Anzeigefilter –> Lastfilter –> Standardfilter –> USB –> USB-Hubfehler, und klicken Sie dann im Bereich Anzeigefilter auf Übernehmen.
Der USB-Fehlerfilter schränkt die Liste der Ereignisse auf die Ereignisse ein, die die in der folgenden Tabelle aufgeführten Kriterien erfüllen.
Filtern von Text | BESCHREIBUNG |
---|---|
(USBPort_MicrosoftWindowsUSBUSBPORT AND NetEvent.Header.Descriptor.Opcode == 34) | USB-Portereignisse mit Opcode 34 sind Portfehler. |
(USBHub_MicrosoftWindowsUSBUSBHUB AND NetEvent.Header.Descriptor.Opcode == 11) | USB-Hubereignisse mit Opcode 11 sind Hubfehler. |
(NetEvent.Header.Descriptor.Level == 0x2) | Ereignisse mit 0x2 sind in der Regel Fehler. |
(USBHub_MicrosoftWindowsUSBUSBHUB AND NetEvent.Header.Descriptor.Id == 210) | USB-Hubereignisse mit der ID 210 sind "USB Hub Exception Logged"-Ereignisse. Weitere Informationen finden Sie unter Grundlegendes zu Fehlerereignissen und Statuscodes. |
Diese Abbildung zeigt den kleineren Satz von Ereignissen, die im Bereich Framezusammenfassung angezeigt werden, nachdem wir den USB-Fehlerfilter auf unser Beispielablaufverfolgungsprotokoll angewendet haben.
Um eine Übersicht über die Fehlersequenz anzuzeigen, können Sie die einzelnen Fehlerereignisse kurz anzeigen. Wichtige zu beachtende Felder sind fid_NtStatus, fid_UsbdStatus und fid_DebugText. Weitere Informationen finden Sie unter Grundlegendes zu Fehlerereignissen und Statuscodes. Klicken Sie zum Deaktivieren eines Filters im Bereich Filter anzeigen auf die Schaltfläche Entfernen.
Benutzerdefinierte Netmon-Filter
Sie können benutzerdefinierte Filter in Netmon erstellen. Die einfachste Methode besteht darin, einen Filter aus Daten auf dem Bildschirm auf eine der folgenden Arten zu erstellen:
- Klicken Sie im Bereich Framedetails mit der rechten Maustaste auf ein Feld, und wählen Sie Ausgewählte Werte zum Anzeigefilter hinzufügen aus.
- Klicken Sie im Bereich Framezusammenfassung mit der rechten Maustaste auf ein Feld, und wählen Sie [Feldname] zum Anzeigefilter hinzufügen aus.
Sie können die Operatoren (z. B. OR, AND und ==) und die Filterwerte ändern, um die entsprechenden Filterausdrücke zu erstellen.
Grundlegendes zu Fehlerereignissen und Statuscodes
In unserem Beispiel für ein unbekanntes Gerät weisen die meisten USB-Hub-Ausnahmen eine fid_DebugText Daten von CreateDeviceFailure auf. Es ist nicht klar, wie schwerwiegend die Ausnahme ist, aber der Debugtext gibt einen Hinweis auf die Ursache: Ein Vorgang im Zusammenhang mit dem neuen Gerät ist fehlgeschlagen. Gehen Sie vorerst davon aus, dass die angrenzenden Ereignisse zum Erstellen eines Gerätefehlers redundant sind. Die letzten beiden Ausnahmen sind CreateDeviceFailure_Popup und GenErr_UserIoctlFailed. Die Popup-Ausnahme klingt wie ein Fehler, der für den Benutzer verfügbar gemacht wurde, aber alle diese Fehler können mit dem unbekannten Geräteproblem zusammenhängen.
USB-Fehlerereignisse und andere Ereignisse enthalten status Werte in ihren Daten, die wertvolle Informationen über das Problem liefern. Informationen zu status Werten finden Sie mithilfe der Ressourcen in der folgenden Tabelle.
Statustyp | Resource |
---|---|
fid_NtStatus | Weitere Informationen finden Sie unter NTSTATUS-Werte. |
Das status Feld eines USB-Anforderungsblocks (URB) oder fid_UsbdStatus | Suchen Sie den Wert als USBD_STATUS in inc\api\usb.h im Windows Driver Kit (WDK). Sie können auch die USBD_STATUS verwenden. In diesem Thema werden die symbolischen Namen und die Bedeutungen der USBD_STATUS Werte aufgelistet. |
Rückwärtslesen von Problemereignissen
Die Ereignisse, die vor den Fehlerereignissen protokolliert werden, können wichtige Hinweise zur Fehlerursache liefern. Sie sollten sich die Ereignisse ansehen, die vor den Fehlern protokolliert werden, um die Grundursache des unbekannten Geräts zu ermitteln. Beginnen Sie in diesem Beispiel vom CreateDeviceFailure_Popup-Ereignis, der vorletzten Ausnahme, zurück. Wählen Sie dieses Ereignis aus, während der USB-Fehlerfilter aktiviert ist, und klicken Sie dann im Bereich Anzeigefilter auf Entfernen. Der USB-Fehlerfilter wird weiterhin im Bereich Anzeigefilter angezeigt, und Sie können ihn später erneut anwenden. Jetzt ist der Filter jedoch deaktiviert, und im Bereich Framezusammenfassung werden alle Ereignisse angezeigt, wie in dieser Abbildung dargestellt.
Die beiden Ereignisse, die unmittelbar vor dem CreateDeviceFailure_Popup-Ereignis protokolliert werden, sind ein Dispatch- und ein Complete-Ereignis einer USB-Steuerungsübertragung. Das Feld fid_USBPORT_Device Portpfad ist für beide Ereignisse null, was angibt, dass das Ziel der Übertragung der Stammhub ist. In der fid_USBPORT_URB_CONTROL_TRANSFER-Struktur des Abschlussereignisses ist der status null (USBD_STATUS_SUCCESS), was angibt, dass die Übertragung erfolgreich war. Fahren Sie mit der Untersuchung der vorherigen Ereignisse fort.
Die nächsten beiden vorherigen Ereignisse sind das vierte (endgültige) Create Device Failed-Ereignis und das vierte (endgültige) CreateDeviceFailure-Ereignis, das wir zuvor untersucht haben.
Das nächste vorherige Ereignis ist Endpoint Close. Dieses Ereignis bedeutet, dass ein Endpunkt nicht mehr verwendet werden kann. Die Ereignisdaten beschreiben sowohl das Gerät als auch den Endpunkt auf diesem Gerät. Der Geräteportpfad ist [1, 0, 0, 0, 0, 0, 0]. Das System, auf dem wir die Ablaufverfolgung ausgeführt haben, verfügt nur über Hostcontroller (Stammhubs) und das Gerät, das wir verbunden haben, sodass dieser Portpfad keinen Hub beschreibt. Der geschlossene Endpunkt muss sich auf dem einzelnen Gerät befinden, das wir angeschlossen haben, und jetzt wissen wir, dass der Pfad des Geräts 1 ist. Es ist wahrscheinlich, dass die Treiber den Zugriff auf den Endpunkt des Geräts aufgrund eines zuvor aufgetretenen Problems nicht möglich gemacht haben. Fahren Sie mit der Untersuchung der vorherigen Ereignisse fort.
Das nächste vorherige Ereignis ist eine abgeschlossene USB-Steuerungsübertragung. Die Ereignisdaten zeigen, dass das Ziel der Übertragung das Gerät ist (der Portpfad ist 1). Die fid_USBPORT_Endpoint_Descriptor-Struktur gibt an, dass die Adresse des Endpunkts 0 ist. Dies ist also der über USB definierte Standard-Steuerungsendpunkt. Der URB-status ist 0xC0000004. Da die status nicht null ist, war die Übertragung wahrscheinlich nicht erfolgreich. Weitere Informationen zu diesem USBD_STATUS Wert finden Sie unter usb.h und Grundlegendes zu Fehlerereignissen und Statuscodes.
#define USBD_STATUS_STALL_PID ((USBD_STATUS)0xC0000004L)
Bedeutung: Das Gerät hat einen Paketbezeichner für den Stillstand zurückgegeben. Welche Anforderung wurde vom Endpunkt angehalten? Die anderen Daten, die für das Ereignis protokolliert wurden, deuten darauf hin, dass es sich bei der Anforderung um eine Standardanforderung für die Gerätesteuerung handelte. Dies ist die analysierte Anforderung:
Frame: Number = 184, Captured Frame Length = 252, MediaType = NetEvent
+ NetEvent:
- MicrosoftWindowsUSBUSBPORT: Complete Internal URB_FUNCTION_CONTROL_TRANSFER
- USBPORT_ETW_EVENT_COMPLETE_INTERNAL_URB_FUNCTION_CONTROL_TRANSFER: Complete Internal URB_FUNCTION_CONTROL_TRANSFER
+ fid_USBPORT_HC:
+ fid_USBPORT_Device:
+ fid_USBPORT_Endpoint:
+ fid_USBPORT_Endpoint_Descriptor:
+ fid_URB_Ptr: 0x84539008
- ControlTransfer:
+ Urb: Status = 0xc0000004, Flags 0x3, Length = 0
- SetupPacket: GET_DESCRIPTOR
+ bmRequestType: (Standard request) 0x80
bRequest: (6) GET_DESCRIPTOR
Value_DescriptorIndex: 0 (0x0)
Value_DescriptorType: (1) DEVICE
_wIndex: 0 (0x0)
wLength: 64 (0x40)
Kombinieren Sie bRequest (GET_DESCRIPTOR) mit dem Value_DescriptorType (DEVICE), und Sie können feststellen, dass die Anforderung get-device descriptor war.
Damit die USB-Enumeration fortgesetzt wird, sollte das Gerät mit seinem Gerätedeskriptor auf diese Anforderung geantwortet haben. Stattdessen hat das Gerät die Anforderung angehalten, was dazu führte, dass die Enumeration fehlschlägt. Daher wurden alle vier Fehler beim Erstellen von Geräten durch verzögerte Anforderungen für den Gerätedeskriptor verursacht. Sie haben festgestellt, dass das Gerät unbekannt ist, da die Enumeration fehlgeschlagen ist, und dass die Enumeration fehlgeschlagen ist, weil das Gerät die Anforderung für seinen Gerätedeskriptor nicht abgeschlossen hat.