The information in this article applies to:
- Microsoft Windows NT Workstation versions 3.5 and 3.51
- Microsoft Windows NT Server versions 3.5 and 3.51
SUMMARY
When you debug problems with Windows NT, it is sometimes necessary to
identify variables or data structures created when Kernel-mode drivers are
initialized. This is a problem, because the Kernel Debugger (I386KD,
ALPHAKD, MIPSKD and PPCKD) only allow break points to be set when the
symbols are loaded, and symbols can only be loaded when their respective
driver is loaded. The following procedure explains how to get around this
situation and how to trace DriverEntry(), which is the first function
called for each driver by the Windows NT I/O manager at boot up.
NOTE: The GUI version of the debugger (WINDBG) allows for breakpoints to be
kept during a remote reboot of Windows NT, but other problems with that
version of the debugger usually require that the console debuggers
(mentioned above) be used.
MORE INFORMATION
- Make sure that the connection between your local debugger and the remote
machine is established and configured properly. To do this, you may want
to break into the target and unassemble some kernel functions (such as
NtUnlockFile()). Also make sure the modem at the target machine is set
to stay enabled on loss of DTR, so your connection is not cut off when
the target machine reboots
- Issue the "!drivers" command to obtain the list of loaded drivers. Note
the sequence in which they appear, as this is the sequence in which they
are loaded after rebooting. Make a note of the driver that precedes the
one you need to debug.
- Reboot the target computer (.reboot). The symbols are unloaded.
- As soon as you see the symbols for NTOSKRNL.EXE loading (this is echoed
to your screen only if you have started the debugger with the "-v"
switch), Press CTRL+C to break into the target.
- Set a break point on IopLoadDriver. This breaks into the system each
time a driver is about to be loaded.
- Let the target continue ("g") until you hit this break point after the
preceding driver (see step 1) is loaded. Your driver is now about to be
loaded.
- Set a break point on MmLoadSystemImage.
- The debugger now breaks every time information is loaded from the disk
into memory (which can happen several times for a single driver).
- Let the target run to the return address of MmLoadSystemImage, by using
the "g" command with the RetAddr for MmLoadSystemImage (For example:
g 8015b677). This return address should take you back into
IopLoadUnloadDriver or IopLoadDriver. You may need to repeat this step
several times until you see the symbols for your driver being loaded.
This takes you to a break point where the symbols for the driver are
loaded, but DriverEntry() has not been called yet. You can now set any BP
you need for this driver, including on DriverEntry().
NOTE: An alternative procedure is as follows:
- Make sure that the connection between your local debugger and the remote
machine is established and configured properly. To do this, you may want
to break into the target and unassemble some kernel functions (such as
NtUnlockFile()). Also make sure the modem at the target machine is set
to stay enabled on loss of DTR, so your connection is not cut off when
the target machine reboots
- Issue the "!drivers" command to obtain the list of loaded drivers. Note
the sequence in which they appear, as this is the sequence in which they
are loaded after rebooting. Make a note of the driver that precedes the
one you need to debug.
- Reboot the target computer (.reboot). The symbols are unloaded.
- As soon as you see the symbols for NTOSKRNL.EXE loading (this is echoed
to your screen only if you have started the debugger with the "-v"
switch), Press CTRL+C to break into the target.
- Issue "g MmLoadSystemImage", do "t" once and get the stack frame:
kd> t
8016651e 55 push ebp
kd> k
ChildEBP RetAddr
ff67ab90 8015b677 ntoskrnl!_MmLoadSystemImage+0x6
ff67ac14 801aece1 ntoskrnl!_IopLoadDriver+0x293
ff67ac38 801ac56e ntoskrnl!_IopInitializeSystemDrivers+0x7f
ff67ad6c 801ab879 ntoskrnl!_IoInitSystem+0x3af
ff67af4c 80132910 ntoskrnl!_Phase1Initialization+0x475
ff67af7c 8013cf4e ntoskrnl!_PspSystemThreadStartup+0x40
00000000 00000000 ntoskrnl!_KiThreadStartup+0x16
- Set a breakpoint at the return address of MmLoadSystemImage:
kd> bp 8015b677
- Issue "g". The debugger will now break after loading a driver image.
When you see the symbols loaded of the driver you want to debug, set a
breakpoint on its DriverEntry function.
|