DOS/4G and DOS/4GW FAQ: Interpreting Error 2001
[Previous Section] *
[Index of FAQ] *
[Next Section]
-
My program generates an error (2001). How do I tell what's going on?
1.
My program generates an error (2001). How do I tell what's going on?
Error 2001 is of the form: exception <exception_number> at
<address>. The address listed is usually that of the faulting
instruction, but in some cases, the address will correspond to the next
instruction in the code after the faulting instruction.
Exceptions that the kernel may trap include the following interrupts:
00h - divide by zero
01h - debug exception
03h - breakpoint
04h - overflow
05h - bounds
06h - invalid opcode
07h - device not available
08h - double fault
09h - overrun
0Ah - invalid TSS
0Bh - segment not present
0Ch - stack fault
0Dh - general protection fault
0Eh - page fault
10h - coprocessor error
The error message is followed by a dump that shows the contents of all
of the CPU registers at the point of the exception.
If the DOS4G option CrashVerbose is not already set to ON, set the
option. This will cause the kernel to print out more information when
your program crashes. Then run the program again. Completing the
following steps will help you find the problem that caused the crash.
1. Record all of the information from the register dump.
2. Determine the circumstances under which the error occurs.
3. Consult you debugger manual, or an Intel 80x86 Programmer's
Reference manual, to determine the circumstances under which
the processor will generate the reported exception.
4. Get the program to fail under your debugger, which should stop the
program as soon as the exception occurs.
5. Determine from the exception context why the processor generated
an exception in this particular instance.
This sample register dump shows the kind of information the kernel
displays when CrashVerbose=ON.
1-> DOS/4G error (2001): exception 0Eh (page fault) at 170:0042C1B2
2-> TSF32: prev_tsf32 67D8
3-> SS 178 DS 178 ES 178 FS 0 GS 20
EAX 1F000000 EBX 0 ECX 43201C EDX E
ESI E EDI 0 EBP 431410 ESP 4313FC
4-> CS:IP 170:0042C1B2 ID 0E COD 0 FLG 10246
CS= 170,USE32,page granular, limit FFFFFFFF, base 0, acc CF9B
SS= 178,USE32,page granular, limit FFFFFFFF, base 0, acc CF93
DS= 178,USE32,page granular, limit FFFFFFFF, base 0, acc CF93
ES= 178,USE32,page granular, limit FFFFFFFF, base 0, acc CF93
FS= 0,USE16,byte granular, limit 0, base 15, acc 0
GS= 20,USE16,byte granular, limit FFFF, base 6AA0, acc 93
5-> CR0: PG1:1 ET:1 TS:0 EM:0 MP:0 PE:1 CR2: 1F000000 CR3: 9067
6-> Crash address (unrelocated) = 1:000001B2
7-> Opcode stream:8A 18 31 D2 88 DA EB 0E 50 68 39 00 43 E8 1D
8-> Stack:
0178:004313FC 000E 0000 0000 0000 C2D5 0042 C057 0042 0170 0000 0000 0000
0178:00431414 0450 0043 0452 0043 0000 0000 1430 0043 CBEF 0042 011C 0000
0178:0043142C C568 0042 0000 0000 0000 0000 0000 0000 F248 0042 F5F8 0042
0178:00431444 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0178:0043145C 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0178:00431474 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
9-> Last 4 ints: 21 @ 170:42CF48/21 @ 170:42CF48/21 @ 170:42CF48/E @ 170:42C1B2/
1. The error message includes a synopsis of the problem. In this case,
the processor signaled a page fault (0Eh) while executing at address
170:0042C1B2.
2. The prev_tsf field is not usually of interest.
3. These are the register values at the time of the exception. The
kernel also displays the interrupt number and error code (pushed on
the stack by the processor for certain exceptions).
4. The kernel describes the descriptors referenced by each segment
register, for your convenience. In general, USE32 segments belong
to your program; USE16 segments generally belong to the DOS extender.
Here, CS points to your program's code segment, and SS, DS, and ES
point to your data segment. FS is null, and GS points to a DOS
extender code segment.
5. The control register information is not of any general interest,
except on a page fault, when CR2 contains the address value that
caused the fault. Since EAX in this case contains the same value,
an attempt to dereference EAX could have caused this particular
fault.
6. The crash address (unrelocated) tells you where the crash occurred
relative to your program's link map. This allows you to know where
the crash occurred even if you can't reproduce the crash in a
debugger.
7. The opcode stream shows the next 16 bytes from the code segment at
the point of the exception. If you disassemble these bytes, you can
tell what instructions caused the crash even without using a debugger.
In this case, 8A 18 is the instruction mov bl, [eax].
8. The Stack: section shows 72 words from the top of the stack.
You may recognize function calls or data from your program
on the stack.
9. The kernel then lists the last four interrupts that it handled in
protected mode, in chronological order (last interrupt listed last).
In this example, the last interrupt issued before the page fault
occurred was an Interrupt 21h at address 170:42CF48. This information
may provide helpful context.
|