The one area in which Windows 98 beats Windows 2000 for debugging is with its Dr. Watson logs. The Windows 98 logs contain far more information, especially about the processes running on the system and the version information for each module. With the information you get from a Windows 98 Dr. Watson log, you'll have a much easier time setting up a duplicate machine to test against.
Much of the crash information logged is the same in Windows 2000 and Windows 98—you just get a whole lot more of it in Windows 98. For example, the Windows 98 Dr. Watson log disassembles each location in the call stack. I'll show only the Details section for a Windows 98 crash because I want to explain some of the extra information you'll see.
Here's the start of the Details section:
*----> Details <----* Command line: "g:\Dev\Book\CD\SourceCode\Output\WDBG.exe" Trap 0e 0000 - Invalid page fault eax=00000000 ebx=0065fba6 ecx=00b938b0 edx=fffdc1a5 esi=005301c0 edi=0065fae4 eip=0040bd2d esp=0065f908 ebp=0065f934 -- -- -- nv up EI pl nz na PE nc cs=0167 ss=016f ds=016f es=016f fs=38d7 gs=382f WDBG.EXE:.text+0xad2d: >0167:0040bd2d 8b4804 mov ecx,dword ptr [eax+04] |
This section shows the full command line and the fault, which is the same as an exception on Windows 2000. After the fault come the usual registers followed by the instruction that caused the crash.
Here Windows 98 is showing some of its 16-bit heritage. These are all the segment registers showing the selector values. For more information, see the Intel processor manuals.
sel type base lim/bot ---- ---- -------- -------- cs 0167 r-x- 00000000 ffffffff ss 016f rw-e 00000000 0000d7a0 ds 016f rw-e 00000000 0000d7a0 es 016f rw-e 00000000 0000d7a0 fs 38d7 rw-- 81630798 00000037 gs 382f rw-- 00657000 0000ffff stack base: 00560000 TIB limits: 0065b000 - 00660000- |
The exception record is a dump of the first field in the EXCEPTION_POINTERS structure when the Dr. Watson debugger is notified of the exception:
-- exception record -- Exception Code: c0000005 (access violation) Exception Address: 0040bd2d (WDBG.EXE:.text+0xad2d) Exception Info: 00000000 ffffffff |
The disassembly shows the current state of the thread. An asterisk delineates the current instruction. (Notice that I removed the code bytes from the disassembly so that it would fit on the page.)
WDBG.EXE:.text+0xad2d: >0167:0040bd2d mov ecx,dword ptr [eax+04] 0167:0040bd11 push esi 0167:0040bd12 push edi 0167:0040bd13 mov eax,cccccccc 0167:0040bd18 mov dword ptr [ebp-20],eax 0167:0040bd1b mov dword ptr [ebp-1c],eax 0167:0040bd1e mov dword ptr [ebp-18],eax 0167:0040bd21 mov dword ptr [ebp-14],eax 0167:0040bd24 mov dword ptr [ebp-10],eax 0167:0040bd27 mov dword ptr [ebp-20],ecx 0167:0040bd2a mov eax,dword ptr [ebp+0c] WDBG.EXE:.text+0xad2d: *0167:0040bd2d mov ecx,dword ptr [eax+04] 0167:0040bd30 cmp dword ptr [ecx],80000003 0167:0040bd36 jz 0040bd5d = WDBG.EXE:.text+0xad5d 0167:0040bd38 mov esi,esp 0167:0040bd3a push 00000382 0167:0040bd3f push 00420030 0167:0040bd44 push 00420064 0167:0040bd49 push +00 0167:0040bd4b call dword ptr [00423ad4] -> BUGSLAYERUTIL.DLL!DiagAssertA 0167:0040bd51 cmp esi,esp 0167:0040bd53 call 00416b5a = MSVCRTD.DLL!_chkesp |