Tenberry Home

Consulting Services

Order DOS/4G


Release Notes


* * *



for Watcom


Interpreting Error 2001

[Previous Section] * [Index of FAQ] * [Next Section]
  1. 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.

[Previous Section] * [Index of FAQ] * [Next Section]
Last modified 2003.02.06. Your questions, comments, and feedback are welcome.