How can I determine where a GPF has occurred?
──────────────────────────────────────────────────────────────────────────────

General Protection Faults are mainly caused by illegal instructions. When
people first see a GPF they assume that the problem is with the linker. This
is not the case. The cause of the problem has been determined at the exact
point where it has occurred.

Had the same program been run in real mode the problem would not have been
detected until much later in the running of the program and an error would
have occurred - although the error message could have been anything and
probably nothing to do with the real problem.

When linking in protected you should always create a .MAP file of the
application so that the results of the GPF can be cross referenced.

This is done with the simple use of a 'MAP A' command on your link line or
within the link script, which will produce an Address map.

When a GPF occurs, MrDebug traps the GPF and reproduces the output in the
Error/GPF window. If you have an up-to-date .MAP file, you can press ◄──┛
and MrDebug will scan the .MAP file for the information required to seek out
and display the meaningful information, but don't blink otherwise you will
miss the map scan!

MrDebug is not going to catch all of the GPF's as sometimes you'll get a GPF
whilst a GPF is being reported in which case you'll have fun tracking the
GPF down as you won't have any information about the first GPF!

Well we thought of that. When a GPF occurs, the first thing that happens is
MrDebug creates a .GPF plain text file that contains the information about
the GPF sufficient enough for MrGPF to use to report the GPF information.

When your run MrGPF, MrGPF will scan the.GPF file first and report the
information that it finds in there, it will then scan the screen to report
on the second GPF and report that as well. So you'll know that 2 GPF's
occurred and that the first GPF reported by MrGPF is always the first GPF to
occur. But please note, this will only work with MrDebug, a MrDebug creates
the .GPF file.

The manual way of locating a GPF.

The output generated by Blinker when a general protection fault or similar
looks something like the following, the bits you need to look at have been
marked.

BLX286 : 1313 : exception error 0D : general protection fault, code = 0000h

Active host is DPMI

Reg Value Limit S┌──┐nt Module File
CS 0137 EDA7 │01│ GPF D:\C700\DEV\MRDEBUG\GPF\GPF.EXE
DS 0177 FFFF └──┛ GPF D:\C700\DEV\MRDEBUG\GPF\GPF.EXE
ES 0000 ****
SS 0177 FFFF 09 GPF D:\C700\DEV\MRDEBUG\GPF\GPF.EXE

[Code byte CS] 00 00 00 00 33 DB 8E C3 [IP] 26 8A 07 2A E4 50 9A 84 70 37
┌────┐
[Registers] AX=01BF BX=0000 CX=0001 DX=467C CS:IP=0137:│00C0│
SI=0032 DI=46A6 BP=3F0C SP=3EFC └────┛
NV UP EI NT PL NZ NA PE NC

[Stack value SS] 467C 0001 0000 4B55 [SP] B5D7 0137 0137 B04D 0000 0000

[Stack frame SS] 0000 0000 468A 04C2 [BP] 3F26 0022 0137 0026 0137 0000

The first number is the extended mode segment number that the currently
executing code is in. The second number is the offset within the segment of
the code. Just look at the map file for the segment and offset, and hey
presto, you've found the target. You probably won't find an exact match to
the offset, just look for the nearest address below the actual GPF location.