📄 guide.gml
字号:
subtracted from for useful effect, but detailing these cases exceed the
scope of this manual.)
.bull
Do not access data at an offset greater than the size of
the associated selector. Attempts to do so result in a fault. This is
one of the greatest strengths of protected mode because most obscure
bugs in real mode code occur when a bad pointer value accesses the wrong
area of memory, or when a buffer overflows and memory beyond the buffer
is overwritten.
.bull
Do not attempt to write to or read from the NULL (zero
value) segment. Attempts to do so results in a fault. In addition to
valid selector values, segment registers can be safely loaded with a
value of 0 but this selector value cannot be used to access memory or
execute code.
.endbull
.note
Do not execute code in a data segment and do not write to data in
the code segment. Use the CauseWay AliasSel function to map a data
selector to the same physical memory area shared by a code selector when
necessary. Even in this case, however, never write to memory using a CS:
code segment override because it always causes a processor fault.
.note
CauseWay handles most of the standard DOS interrupts
transparently. When passing pointers to buffers for software interrupt
calls not handled by CauseWay, create the buffers in low (conventional)
DOS memory using the GetMemDOS function of the CauseWay API. In
addition, convert the pointers from protected mode selector:offset pairs
to real mode segment:offset pairs prior to the interrupt, and back upon
your return from the interrupt.
.endnote
.*
.*
.chap CW.ERR File Information Format
.*
.np
.ix 'CW.ERR'
The following information describes the format of the CW.ERR file that
CauseWay creates if an exception occurs in a CauseWay application. This
information can be very useful in tracking down exactly where and why an
exception occurred.
.*
.section Quick Reference Guide
.*
.np
If you do not know how to interpret assembly language or CPU
instructions, and you want better detail on the location of an
exception, you can frequently identify which routine caused the
exception by cross-referencing the MAP file with the CW.ERR file.
Following is a short guide to determine the offending routine.
.np
Look at the value after the dash (-) listed for the CS segment register
at the beginning of the ninth line in CW.ERR. This should be an eight
digit number starting with several zeros. Now look at the MAP file of
your application. Following the program, creation date and time lines in
the MAP file is a listing of program segments showing their start, stop,
length, name, class and count. Find the segment which has a start
address equal to the eight digit number listed above. This is the entry
for the program segment where the exception occurred.
.np
Locate the public symbols listed by address in the MAP file. Each
symbol in the program is listed in ascending address order. The address
is composed of two values separated by a colon (:). Find the address
group which begins with the eight digit number given above for CS
segment register without the last digit. For example, if the CS eight
digit number was 000205E0, look for an address beginning with 0000205E.
If you cannot find any addresses beginning with the number, either no
routines in the segment were declared public or else you have a version
of the MAP file that was created at a different time than the
application EXE file which generated the CW.ERR file.
.np
If there is only one address beginning with the number, you have located
the offending routine. If there is more than one address, examine the
EIP value in CW.ERR. The EIP value is located in the middle of the
seventh line immediately following the "EIP=" text. This value is the
offset in the segment where the exception occurred. Find the symbol in
the address group which has an address value following the ":" that is
closest to the EIP but does not exceed the EIP value. This name of the
symbol is the name of the routine which generated the exception. To
continue our example, if you have the following four symbols of address
0000205E in the first half of the address line in the map file :
.millust begin
0000205E:000008DC __DBFGOHOT
0000205E:00000944 __DBFGOCOLD
0000205E:00000986 __DBFGOTOID
0000205E:00000AEE __DBFGOTOP
.millust end
and the EIP value is 00000953, the closest routine name that does not
exceed the EIP value in the second half of the address line is
.mono __DBFGOCOLD.
Therefore, the exception occurred in the
.mono __DBFGOCOLD
routine.
.np
This method of locating the exception is not foolproof since it requires
that the routine creating the exception in the program segment be
declared public, but it should work for the majority of cases.
.*
.section Sequence
.*
.np
The first line in CW.ERR is the CauseWay copyright message including the
version of CauseWay used in the program. The version number may prove
useful in tracking down problems that have been addressed in later
versions of CauseWay.
.np
The version is followed by the exception number and error code. These
numbers, as well as all others in the CW.ERR file, are in hexadecimal.
The values listed are those reported by the processor when the exception
occurred. Detailed information about the significance of the values can
be obtained in most 386 and above reference books. Typically the
exception value will be 0DH, a General Protection Fault; 0CH, a stack
fault usually due to stack overflow or underflow; or 0EH, a page fault
due to improper memory reference. The error code is generally of little
use for debugging purposes.
.np
Next comes the general register values which indicate the state of the
program when the exception occurred. The significance of register values
is entirely dependent on the program being run at the time. CS:EIP
register values can help track down the problem area by pinpointing
exactly where in the code the exception occurred. Other register values
may help determine why the exception occurred. In particular, look for
use of registers as memory indices with values beyond the limit of the
associated selector.
.np
Next, the segment register values are displayed as a real selector value
followed by the program relative value in bytes. If the second value is
non-numeric (xxxxxxxx) then the segment register didn't contain a
selector value allocated to the program at load time, although the value
may be valid if it was dynamically allocated by the operating program.
If there is a second value, it also appears in the program's .MAP
file as the segment start address. This shows which segment a segment
register is pointing to at the time of the exception. The CS (Code
Segment) register points to the segment containing the code which is
executing. The EIP register value indicates the offset within the CS
segment where the exception occurred. With these two values, you can
not only determine the segment, but the routine within the segment
closest to where the exception occurred.
.np
Segment register values are also useful in determining why an exception
occurred. One common error is using an invalid selector value in DS,
ES, FS, or GS. A segment register value of zero does not automatically
indicate problem, but will cause a GPF if used to read or write to
memory. In particular, be highly suspicious of DS and ES segment
register values of 0000-xxxxxxxx since they are almost constantly used to
to access memory. A zero value in DS or ES usually indicates
a bad (NULL) memory pointer passed to a routine.
.np
Next, the processor control register values are listed. These registers
are unlikely to be of much use for debugging and will only be filled in
when not running under a true DPMI host. For an exception 0Eh (page
fault), CR2 is the linear address that was accessed for which no memory
was mapped in. This may help track down the problem area.
.np
Info Flags comes next. This value is returned by CauseWay's Info API
function. Check it against the documentation for Info in the CauseWay
API chapter to determine some aspects of the environment in which the
program was running when the exception occurred, e.g. whether a DPMI
host was being used.
.np
Program Linear Load Address follows Info Flags. This value is th
executable's load address in linear memory. It corresponds to one of
the linear memory block entries described later.
.np
In flat models, the EIP value minus the program linear load address is
the address offset of the faulting location relative to the start of the
program.
.np
Following Program Linear Load Address is a display of the next 128 byte
values at the CS:EIP location when the exception occurred. These are
the hexadecimal byte values of the CPU instructions at the time of the
exception. 386 reference books or some debuggers can be used to
reconstruct the instruction operation codes that correspond to these
hexadecimal byte values.
.np
The SS:ESP displays follows CS:EIP. This display shows the last 128
bytes values stored on the CPU stack.
.np
SS:EBP is next. It shows 128 byte values of the current stack frame
negatively and positively offset from the current EBP value. C and other
high level language routines use the EBP register to reference
parameters passed on the stack and this display can show which
parameters were passed.
.np
The resource tracking details come next. Selectors are listed with the
following headings:
.*
.millust begin
sel base limit type D mem count
.millust end
.*
.synote
.mnote sel
Selector value.
.mnote base
Linear base address of selector.
.mnote limit
Limit of selector.
.mnote type
CODE or DATA.
.mnote D
16 or 32 to signify segment D bit.
.mnote mem
Y or N to indicate if the selector has a memory
block associated with it.
.mnote count
segment count in MAP file, xxxx if dynamically allocated.
.esynote
.*
The selector list is finished off with a display of the total number of
selectors allocated to the program. For example:
.millust begin
Total selectors: 0107
.millust end
Linear memory blocks are listed following the selector list, and contain
the following headings:
.*
.millust begin
handle base length
.millust end
.*
.synote
.mnote handle
Linear memory [de]allocation uses handles to control
the blocks. This field is the block's handle.
.mnote base
Linear base address of the memory block.
.mnote length
Length of the block in bytes.
.esynote
The linear memory list ends with a display of the total linear memory
allocated to the program, the real (rounded to 4KB pages) memory
allocated in parentheses, and finally the total number of memory
blocks. For example:
.millust begin
Total Linear memory: 000FEAC9 (001AA000) in 00000103 blocks
.millust end
Entries in the selector list that have Y under "mem" should have a
corresponding entry in the linear memory list.
.np
Linear memory locks are listed after the linear memory block list and
contain the following headings:
.*
.millust begin
base length
.millust end
.*
.synote
.mnote base
Linear base of the locked region.
.mnote limit
Length of the locked region.
.esynote
.*
Note: These values are passed by the program but the actual
values have the base rounded down a page and the length rounded up a
page to match 4KB boundary restrictions on locking. The values are
reported in CW.ERR without using a rounded format to make it easier to
cross reference this list to the other lists in CW.ERR.
.np
Next, protected mode interrupt vectors are listed with the following
headings:
.*
.millust begin
No sel offset
.millust end
.*
.synote
.mnote No
Vector number.
.mnote sel
Selector value for handler.
.mnote offset
Offset value for handler.
.esynote
.*
This information allows a cross-reference with the other lists to ensure
CauseWay application installed handlers have been properly made.
.np
Next, protected mode exception vectors are listed using the same format
as protected mode interrupts.
.np
After the protected mode exception vector list, real mode interrupt
vectors are listed. They are shown in the same format as protected mode
interrupts although the selector values are real mode segment values.
.np
Only those interrupt and exception vectors altered by the program will
be listed.
.np
Lastly, Call-Backs are listed in the CW.ERR file. They list all active
Call-Backs for the active application at the time of its termination.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -