Freigeben über


Debuggen eines Interrupt-Sturms

Eines der allgemeinsten Beispiele für ein blockiertes System ist ein Interrupt-Sturm. Ein Interrupt-Sturm ist ein ausgelöstes Interrupt-Signal, das im bestätigten Zustand bleibt.

Die folgenden Ereignisse können einen Interrupt-Sturm verursachen:

  • Ein Hardware-Gerät gibt sein Interrupt-Signal nicht frei, nachdem es vom Gerätetreiber dazu aufgefordert wurde.

  • Ein Gerätetreiber weist seine Hardware nicht an, das Interrupt-Signal freizugeben, weil er nicht erkennt, dass der Interrupt von seiner Hardware ausgelöst wurde.

  • Ein Gerätetreiber beansprucht den Interrupt für sich, obwohl der Interrupt nicht von seiner Hardware ausgelöst wurde. Diese Situation kann nur auftreten, wenn sich mehrere Geräte denselben IRQ teilen.

  • Das Edge Level Control Register (ELCR) ist nicht korrekt festgelegt.

  • Edge- und Level-Interrupt-ausgelöste Geräte teilen sich einen IRQ (z. B. ein COM-Port und ein PCI-SCSI-Controller).

Dieses Beispiel demonstriert eine Methode zur Erkennung und Behebung eines Interrupt-Sturms.

Wenn sich der Computer aufhängt, verwenden Sie einen Kernel-Debugger, um einzugreifen. Verwenden Sie den Erweiterungsbefehl !irpfind, um nach anstehenden IRPs zu suchen. Verwenden Sie dann die Erweiterung !irp, um Details über alle ausstehenden IRPs abzurufen. Zum Beispiel:

kd> !irp 81183468
Irp is active with 2 stacks 2 is current (= 0x811834fc)
 No Mdl Thread 00000000:  Irp stack trace.
     cmd  flg cl Device   File     Completion-Context
 [  0, 0]   0  0 8145f470 00000000 00000000-00000000
               \Driver\E100B
                        Args: 00000000 00000000 00000000 00000000
>[ 16, 2]   0 e1 8145f470 00000000 8047f744-814187a8 Success Error Cancel pending
               \Driver\E100B    ntoskrnl!PopCompleteSystemPowerIrp
                        Args: 00000000 00000000 00000002 00000002 

Dieses Beispiel zeigt, dass \driver\e100b die IRP für ntoskrnl!PopCompleteSystemPowerIrp nicht zurückgegeben hat. Er scheint festzustecken und möglicherweise einen Interrupt-Sturm zu verursachen.

Um das zu untersuchen, verwenden Sie den Befehl kb, um einen Stack-Trace anzufordern. Zum Beispiel:

kd> kb
ChildEBP RetAddr  Args to Child
f714ee68 8046355a 00000001 80068c10 00000030 ntoskrnl!RtlpBreakWithStatusInstruction
f714ee68 80067a4f 00000001 80068c10 00000030 ntoskrnl!KeUpdateSystemTime+0x13e
f714eeec 8046380b 01001010 0000003b f714ef00 halacpi!HalBeginSystemInterrupt+0x83
f714eeec 80463c50 01001010 0000003b f714ef00 ntoskrnl!KiChainedDispatch+0x1b
f714ef78 80067cc2 00000000 00000240 8000017c ntoskrnl!KiDispatchInterrupt
f714ef78 80501cb5 00000000 00000240 8000017c halacpi!HalpDispatchInterrupt2ndEnt  

Beachten Sie, dass der Abschnitt, der mit halacpi!HalBeginSystemInterrupt beginnt, ein Interrupt-Dispatch ist. Wenn Sie den Befehl g verwenden und erneut eingreifen, sehen Sie höchstwahrscheinlich einen anderen Stack-Trace, aber immer noch eine Interrupt-Meldung. Um festzustellen, welcher Interrupt für den Systemstillstand verantwortlich ist, sehen Sie sich den zweiten Parameter an, der an HalBeginSystemInterrupt übergeben wird (in diesem Fall 0x3B). Die Standardregel besagt, dass der angezeigte Interrupt-Vektor (0x3B) die IRQ-Zeile plus 0x30 ist, der Interrupt hat also die Nummer 0xB. Wenn Sie einen weiteren Stack-Trace ausführen, erhalten Sie möglicherweise mehr Informationen darüber, welches Gerät den Interrupt Service Request (ISR) ausgegeben hat. In diesem Fall führt ein zweiter Stack-Trace zu folgendem Ergebnis:

kd> kb
ChildEBP RetAddr  Args to Child
f714ee24 8046355a 00000001 00000010 00000030 ntoskrnl!RtlpBreakWithStatusInstruction
f714ee24 bfe854b9 00000001 00000010 00000030 ntoskrnl!KeUpdateSystemTime+0x13e
f714eed8 f7051796 00000000 80463850 8143ec88 atimpab!AtiInterrupt+0x109
f714eee0 80463850 8143ec88 81444038 8046380b VIDEOPRT!pVideoPortInterrupt+0x16
f714eef8 80463818 00000202 0000003b 80450bb8 ntoskrnl!KiChainedDispatch2ndLvl+0x28
f714eef8 80463c50 00000202 0000003b 80450bb8 ntoskrnl!KiChainedDispatch+0x28
f714ef78 80067cc2 00000000 00000240 8000017c ntoskrnl!KiDispatchInterrupt
f714ef78 80501cb5 00000000 00000240 8000017c halacpi!HalpDispatchInterrupt2ndEntry+0x1b
f714f084 8045f744 f714f16c 00020019 f714f148 ntoskrnl!NtCreateKey+0x113
f714f084 8042e487 f714f16c 00020019 f714f148 ntoskrnl!KiSystemService+0xc4
f714f118 804ab556 f714f16c 00020019 f714f148 ntoskrnl!ZwCreateKey+0xb
f714f184 8041f75b f714f1e8 8000017c f714f1d0 ntoskrnl!IopCreateRegistryKeyEx+0x4e
f714f204 804965cd 8145f630 00000000 00000001 ntoskrnl!IopProcessSetInterfaceState+0x93
f714f220 bfee1eb9 8145f630 00000000 8145f5a0 ntoskrnl!IoSetDeviceInterfaceState+0x2b
f714f254 bfedb416 00000004 00000800 0045f570 NDIS!ndisMCommonHaltMiniport+0x1f
f714f268 bfed4ddb bfed0660 811a2708 811a2708 NDIS!ndisPmHaltMiniport+0x9a
f714f288 bfed5146 811a2708 00000004 8145f570 NDIS!ndisSetPower+0x1d1
f714f2a8 8041c60f 81453a30 811a2708 80475b18 NDIS!ndisPowerDispatch+0x84
f714f2bc 8044cc52 80475b18 811a2708 811a279c ntoskrnl!IopfCallDriver+0x35
f714f2d4 8044cb89 811a279c 811a2708 811a27c0 ntoskrnl!PopPresentIrp+0x62 

Das System führt gerade die ISR für die Grafikkarte aus. Das System führt die ISR für jedes der Geräte aus, die sich IRQ 0xB teilen. Wenn kein Prozess den Interrupt beansprucht, wartet das Betriebssystem unendlich lange und fordert die Treiber-ISRs auf, den Interrupt zu verarbeiten. Es ist auch möglich, dass ein Prozess den Interrupt bearbeitet und stoppt, aber wenn die Hardware defekt ist, kann der Interrupt einfach wieder aktiviert werden.

Verwenden Sie die Erweiterung !arbiter 4, um festzustellen, welche Geräte auf IRQ 0xB liegen. Wenn nur ein Gerät auf IRQ 0xB liegt, haben Sie die Ursache des Problems gefunden. Wenn sich mehr als ein Gerät den Interrupt teilt (in 99 % der Fälle), müssen Sie das Gerät isolieren, indem Sie entweder LNK-Knoten manuell programmieren (was den Systemstatus beeinträchtigt) oder indem Sie Hardware entfernen oder deaktivieren.

kd> !arbiter 4
DEVNODE 8149a008 (HTREE\ROOT\0)
  Interrupt Arbiter "RootIRQ" at 80472a20
    Allocated ranges:
      0000000000000000 - 0000000000000000   B   8149acd0
      0000000000000001 - 0000000000000001   B   8149acd0
      0000000000000002 - 0000000000000002   B   8149acd0
      0000000000000003 - 0000000000000003   B   8149acd0
      0000000000000004 - 0000000000000004   B   8149acd0
      0000000000000005 - 0000000000000005   B   8149acd0
      0000000000000006 - 0000000000000006   B   8149acd0
      0000000000000007 - 0000000000000007   B   8149acd0
      0000000000000008 - 0000000000000008   B   8149acd0
      0000000000000009 - 0000000000000009   B   8149acd0
      000000000000000a - 000000000000000a   B   8149acd0
      000000000000000b - 000000000000000b   B   8149acd0
      000000000000000c - 000000000000000c   B   8149acd0
 000000000000000d - 000000000000000d   B   8149acd0
      000000000000000e - 000000000000000e   B   8149acd0
 000000000000000f - 000000000000000f   B   8149acd0
      0000000000000010 - 0000000000000010   B   8149acd0
      0000000000000011 - 0000000000000011   B   8149acd0
      0000000000000012 - 0000000000000012   B   8149acd0
      0000000000000013 - 0000000000000013   B   8149acd0
      0000000000000014 - 0000000000000014   B   8149acd0
      0000000000000015 - 0000000000000015   B   8149acd0
      0000000000000016 - 0000000000000016   B   8149acd0
      0000000000000017 - 0000000000000017   B   8149acd0
      0000000000000018 - 0000000000000018   B   8149acd0
      0000000000000019 - 0000000000000019   B   8149acd0
      000000000000001a - 000000000000001a   B   8149acd0
      000000000000001b - 000000000000001b   B   8149acd0
      000000000000001c - 000000000000001c   B   8149acd0
      000000000000001d - 000000000000001d   B   8149acd0
 000000000000001e - 000000000000001e   B   8149acd0
      000000000000001f - 000000000000001f   B   8149acd0
 0000000000000020 - 0000000000000020   B   8149acd0
      0000000000000021 - 0000000000000021   B   8149acd0
      0000000000000022 - 0000000000000022   B   8149acd0
      0000000000000023 - 0000000000000023   B   8149acd0
      0000000000000024 - 0000000000000024   B   8149acd0
      0000000000000025 - 0000000000000025   B   8149acd0
      0000000000000026 - 0000000000000026   B   8149acd0
      0000000000000027 - 0000000000000027   B   8149acd0
      0000000000000028 - 0000000000000028   B   8149acd0
      0000000000000029 - 0000000000000029   B   8149acd0
      000000000000002a - 000000000000002a   B   8149acd0
      000000000000002b - 000000000000002b   B   8149acd0
      000000000000002c - 000000000000002c   B   8149acd0
 000000000000002d - 000000000000002d   B   8149acd0
      000000000000002e - 000000000000002e   B   8149acd0
 000000000000002f - 000000000000002f   B   8149acd0
      0000000000000032 - 0000000000000032   B   8149acd0
      0000000000000039 - 0000000000000039 S     814776d0  (ACPI)
    Possible allocation:
      < none >

    DEVNODE 81476f28 (ACPI_HAL\PNP0C08\0)
      Interrupt Arbiter "ACPI_IRQ" at bfff10e0
        Allocated ranges:
          0000000000000000 - 0000000000000000   B   81495bb0
          0000000000000001 - 0000000000000001       814952b0  (i8042prt)
          0000000000000003 - 0000000000000003 S     81495610  (Serial)
          0000000000000004 - 0000000000000004   B   8149acd0
          0000000000000006 - 0000000000000006       81495730  (fdc)
          0000000000000008 - 0000000000000008       81495a90
          0000000000000009 - 0000000000000009 S     814776d0  (ACPI)
          000000000000000b - 000000000000000b S
            000000000000000b - 000000000000000b S     81453c30  (ds1)
            000000000000000b - 000000000000000b S     81453a30  (E100B)
            000000000000000b - 000000000000000b S     81493c30  (uhcd)
            000000000000000b - 000000000000000b S     8145c390  (atirage3)
          000000000000000c - 000000000000000c       814953d0  (i8042prt)
 000000000000000d - 000000000000000d   B   81495850
          000000000000000e - 000000000000000e       8145bb50  (atapi)
 000000000000000f - 000000000000000f       8145b970  (atapi)
        Possible allocation:
          < none >

In diesem Fall verwenden Audio, Universal Serial Bus (USB), Netzwerkkarte (NIC) und Video alle denselben IRQ.

Um herauszufinden, welche ISR den Besitz des Interrupts beansprucht, untersuchen Sie den Rückgabewert der ISR. Zerlegen Sie einfach die ISR mit dem Befehl U mit der in der Anzeige !arbiter angegebenen Adresse und legen Sie einen Haltepunkt auf der letzten Anweisung der ISR fest (die eine "ret"-Anweisung sein wird). Beachten Sie, dass die Verwendung des Befehls g <Adresse> dem Festlegen eines Haltepunkts an dieser Adresse entspricht:

kd> g bfe33e7b
ds1wdm!AdapterIsr+ad:
bfe33e7b c20800           ret     0x8 

Verwenden Sie den Befehl r, um die Register zu untersuchen. Sehen Sie sich insbesondere das EAX-Register an. Wenn der Inhalt des EAX-Registers im folgenden Code-Beispiel etwas anderes als Null ist, hat dieser ISR den Interrupt beansprucht. Andernfalls wurde der Interrupt nicht beansprucht, und das Betriebssystem ruft die nächste ISR auf. Dieses Beispiel zeigt, dass die Grafikkarte den Interrupt nicht beansprucht:

kd> r
eax=00000000 ebx=813f4ff0 ecx=00000010 edx=ffdff848 esi=8145d168 edi=813f4fc8
eip=bfe33e7b esp=f714eec4 ebp=f714eee0 iopl=0         nv up ei pl zr na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000246
ds1wdm!AdapterIsr+ad:
bfe33e7b c20800           ret     0x8 

Tatsächlich wird der Interrupt in diesem Fall von keinem der Geräte auf IRQ 0xb beansprucht. Wenn Sie auf dieses Problem stoßen, sollten Sie auch überprüfen, ob die einzelnen mit dem Interrupt verbundenen Hardwarekomponenten tatsächlich aktiviert sind. Bei PCI ist das ganz einfach: Sehen Sie sich das CMD-Register an, das von der Erweiterung !pci ausgegeben wird:

kd> !pci 0 0
PCI Bus 0
00:0  8086:7190.03  Cmd[0006:.mb...]  Sts[2210:c....]  Device  Host bridge
01:0  8086:7191.03  Cmd[0107:imb..s]  Sts[0220:.6...]  PciBridge 0->1-1  PCI-PCI bridge
03:0  1073:000c.03  Cmd[0000:......]  Sts[0210:c....]  Device  SubID:1073:000c Audio device
04:0  8086:1229.05  Cmd[0007:imb...]  Sts[0290:c....]  Device  SubID:8086:0008 Ethernet
07:0  8086:7110.02  Cmd[000f:imb...]  Sts[0280:.....]  Device  ISA bridge
07:1  8086:7111.01  Cmd[0005:i.b...]  Sts[0280:.....]  Device  IDE controller
07:2  8086:7112.01  Cmd[0005:i.b...]  Sts[0280:.....]  Device  USB host controller
07:3  8086:7113.02  Cmd[0003:im....]  Sts[0280:.....]  Device  Class:6:80:0

Beachten Sie, dass das CMD-Register des Audio-Chips (Label „Audio Device“) Null ist. Das bedeutet, dass der Audio-Chip zu diesem Zeitpunkt deaktiviert ist. Das bedeutet auch, dass der Audio-Chip nicht in der Lage ist, auf Zugriffe des Treibers zu reagieren.

In diesem Fall muss der Audio-Chip manuell wieder aktiviert werden.