GEOS SDK TechDocs
|
|
5.3 Breakpoints and Code Stepping
|
5.5 Other Important Commands
The commands in this section all deal with the examination, manipulation, or modification of the memory used by an application. Memory from individual bytes to complex data structures such as objects can be displayed and examined. These commands fall into the following groups:
The commands in this section are often used with each other and with the code-stepping and breakpoint commands in order to pinpoint bugs in an application's code. Breakpoints can be set, code can be stepped through, and then the memory that the code uses can be examined.
Some related commands defined in the Reference chapter are
down
,
func
,
handles
,
hgwalk
,
impliedgrab
,
penum
,
phandle
,
pinst
,
piv
,
precord
,
skip
,
systemobj
,
up
, and
where
.
bytes, words, dwords, frame, backtrace, why, listi
The commands in this group are used to look at simple blocks of memory without modification. They are defined fully in the entries below.
bytes [<addr>] [<length>]
words [<addr>] [<length>]
dwords [<addr>] [<length>]
The
bytes
,
words
, and
dwords
commands are essentially the same except that each looks at a different sized piece of memory. These commands will display the memory as a pointer to a dump of bytes, words, or dwords using the given or most recent (if no address is given) address.
The
bytes
command additionally displays the dump as its ASCII character representation, if any. These three commands are used to examine memory on a very basic level and are useful only if the user knows what the bytes, words, or dwords should or should not be and so can spot any problems. For example, if a certain character string such as "Application" is supposed to be stored at the address given by
fileType
and the command
[hello3:0] 11 => bytes fileType
dumps the characters "noitacilppA", then there is most likely a problem.
These commands will automatically use the given
addr
as a pointer to the memory to be examined. If Return is hit many times in a row, the result will be to examine adjacent pieces of memory. (See The words Command
.)
Swat Display 3-6 The words Command
(mess1:0) 15 => words themeSongBuf Addr: +0 +2 +4 +6 +8 +a +c +e 0040h: 0004 0000 0049 0000 0004 0001 0083 0000 (mess1:0) 16 => words Addr: +0 +2 +4 +6 +8 +a +c +e 004eh: 0000 0006 0004 0028 0000 0001 020b b800 (mess1:0) 17 => !! words Addr: +0 +2 +4 +6 +8 +a +c +e 005ch: b800 000c 0020 0002 0001 0000 0001 020b (mess1:0) 18 => !! words Addr: +0 +2 +4 +6 +8 +a +c +e 006ah: 020b b800 000c 0010 0002 0001 000a 0010
Here the
words
command examines a buffer in memory. When this command is repeated without arguments, it will display memory continuing where the last command left off. Note the use of the
!!
command to repeat the previous command.
backtrace [<frames to list>]
frame <subcommand>
The
backtrace
and
frame
commands are used to examine data that has been pushed onto the stack. An application may crash in a routine that is correctly written but has been passed bad data.
The
backtrace
command prints out a list of all the active frames for the current patient. Then the user can choose a particular frame to examine using one of the
frame
subcommands. The
frame
command is used to access frames that have been pushed onto the stack, where a
frame
is the information for a routine that needs to be saved when it calls another routine.
The
frame
and
backtrace
commands can be used together to print the active frames with
backtrace
and then access data in these frames with
frame
. However, most of the
frame
subcommands expect a token for a frame, not the frame number given by the backtrace command. To get this token, the
top
,
cur
and
next
subcommands are used. Then the other
frame
subcommands can be used with the token to further examine the
frame
data. See also the reference information for the frame command.
Death due to SOUND_BAD_EVENT_COMMAND Execution died in patient sound: SoundHandleTimerEvent+63: MOV AX, 7 (0007h) *** No explanation available *** Interrupt 3: Breakpoint trap Stopped in FatalError, address 1844h:0163h SoundHandleTimerEvent+63: MOV AX, 7 (0007h) (mess1:0) 2 => backtrace 1: near FatalError(), 1844h:0163h 2: far AppFatalError(), 1844h:0163h * 3: far SoundHandleTimerEvent(), 2cb2h:003fh 4: far SoundLibDriverPlaySimpleFM(), 6247h:0062h 5: far ResourceCallInt(), 1844h:1492h 6: far SoundLibDriverStrategy(), 2cb2h:0ab2h 7: near SoundCallLibraryDriverRoutine(), 629ch:00feh 8: far SoundPlayMusic(), 629ch:0028h 9: far ResourceCallInt(), 1844h:1492h 10: far SOUNDPLAYMUSICNOTE(mh = ^h42b0h (at 753ch), priority = 1eh, tempo = 4h , flags = 80h), 62d6h:00f3h 11: far ResourceCallInt(), 1844h:1492h 12: far Mess1Draw(), MESS1.GOC:307 13: far MESS1PROCESSMETA_EXPOSED(win = 3a60h, message = 69 (invalid), oself = 3ee0h:0000h), MESS1.GOC:362 14: far ResourceCallInt(), 1844h:1492h MSG_META_EXPOSED (3a60h 0000h 0000h) sent to Mess1ProcessClass (^l20f0h:0h) 16: near ObjCallMethodTableSaveBXSI(), 1844h:9ea5h 17: far SendMessage(), 1844h:9d9bh 18: far ObjMessage(), 1844h:1d9ch 19: far MessageDispatchDefaultCallBack(), 1844h:1c72h 20: far MessageProcess(callBack = 1844h:1c68h (geos::kcode::MessageDispatchDef aultCallBack)), 1844h:1c15h 21: far MessageDispatch(), 1844h:1b31h 22: far ThreadAttachToQueue(), 1844h:bd2ch (mess1:0) 3 => frame 12 Mess1Draw+302: MOV AX, 100 (0064h)
print, hwalk, lhwalk, objwalk, pobject, gentree, vistree, vup, gup
The commands in this group are used to examine complex data structures in GEOS.
print <expression>
The
print
command is used to print out the value of the given
expression
argument. The
expression
argument is normally some sort of typed address. When there is no type for the
expression
, then its offset is printed.
The power of this command lies in its ability to print any type at any address; thus, it is used frequently to print out the values of important expressions such as registers or variables. The
print
command also takes many flags which control the way in which the value of the
expression
is displayed such as in decimal or hexadecimal. See the Reference chapter for more information on the flags for the
print
command.
hwalk [<patient>]
Use the
hwalk
(heap walk) command to display blocks on the global heap. Its output can be tailored in various ways according to how the
flags
are set. If a
patient
is given, then
hwalk
will only print the blocks owned by that patient. There are many fields in the listing such as the handle, address, and type of each block. By examining these fields, the user can get an overall sense of how the global heap is being managed, whether any block looks too big or too small, and what the handles of important blocks are. (See The hwalk Command
.)
Swat Display 3-8 The hwalk Command
(mess1:0) 6 => hwalk mess1 HANDLE ADDR SIZE FLAGS LOCK OWNER IDLE OINFO TYPE ---------------------------------------------------------------- 20f0h 41ebh 2272 FIXED n/a mess1 n/a 1h R#1 (dgroup) 4160h 58eah 448 sDS a 1 mess1 105eh 1h R#2 (MESS1_TEXT) 3a60h 59adh 784 s SL 0 mess1 0:03 1h WINDOW 4bb0h 6176h 560 s SL 0 mess1 0:05 1h WINDOW 3970h 6232h 336 s SL 0 mess1 0:03 1h GSTATE 3ee0h 633ch 160 s S a 0 mess1 0:05 49c0h Geode 4950h 63beh 1280 s SL 0 mess1 0:05 49c0h OBJ(mess1:0) 4340h 640eh 1328 SL 0 mess1 0:05 49c0h R#3 (INTERFACE) 42b0h 753ch 96 s S 4 mess1 1249h 1h 4bd0h 7542h 96 s S 0 mess1 0:01 1h 41b0h 89d4h 896 SL 0 mess1 0:05 49c0h R#4 (APPRESOURCE) 4270h 99e1h 32 s S 0 mess1 0:05 1h Total bytes allocated: 8288 (mess1:0) 7 =>
lhwalk [<addr>]
objwalk [<addr>]
The
lhwalk
(local heap walk) command is used to display information about a local memory heap, and the
objwalk
command is used to print out information about an object block. After using
hwalk
to locate a specific block,
lhwalk
or
objwalk
can be used to print out information about that particular block. These commands also print out fields of information which include the local handle, the address, size, and type of data or object. See the Reference chapter for more information on the fields printed by
lhwalk
and
objwalk
. (See The objwalk Command
.)
Swat Display 3-9 The objwalk Command
(mess1:0) 11 => objwalk ^h4340h Heap at 640eh:0 (^h4340h), Type = LMEM_TYPE_OBJ_BLOCK In use count = 3, Block size = 1328, Resource size = 59647 para (192 bytes) HANDLE ADDRESS SIZE FLAGS CLASS (NAME) ------ ------- ---- ----- ------------ 001ch 56h 1eh --- *flags* 001eh 76h c1h D RO GenPrimaryClass (Mess1Primary) 0020h 1aah ceh D RO GenViewClass (Mess1View) 0022h 166h 32h ID O OLGadgetAreaClass 0024h 19ah eh I 0026h 492h 6bh D O GenValueClass 0028h 2deh 6bh D O GenValueClass 002ah 37eh a6h ID O GenInteractionClass 002ch 44ah 46h ID O OLMenuBarClass 002eh 13ah bh ID 0030h 426h 22h ID O OLMenuButtonClass Free handles = 17, null handles = 0 Objects = 8, 4 of them marked ignoreDirty (mess1:0) 12 =>
pobject [<addr>] [<print level>]
The
pobject
(print object) command (often abbreviated
pobj
) is used to print out the entire instance data chunk of an object. You can use
gentree
,
vistree
, or
hwalk
and
objwalk
to get the handles for an object; once you have them, use
pobj
with the handles, as follows:
[hello3:0] 7 => pobj ^l0x43d0:0x0022
will print out the instance data chunk specified by that optr.
Any valid address expression, such as a dereferenced object name, may be used as an
addr
. Additionally, the print level can be changed to print just the headings to each of the master levels and an address history number. The
pobject
command is used to verify that the object is behaving correctly and that its instance variables (if any) are correct. (See The pobject Command
.)
Swat Display 3-10 The pobject Command
[lesink:0] 10 => pobj ^l4710h:0020h
*UpTextView::UpTextViewClass (@7, ^l4710h:0020h)
master part: Gen_offset(123) -- UpTextViewInstance
@8: {UpTextViewInstance (^h18192:622)+123} = {
MetaBase Gen = {
ClassStruct _far *MB_class = 360ah:162fh (motif::dgroup::OLPaneClass)
}
LinkPart GI_link = {
dword LP_next = 4710h:001fh
}
CompPart GI_comp = {
dword CP_firstChild = 4710h:002ah
}
word GI_visMoniker = 0h
word GI_kbdAccelerator = 0h
byte GI_attrs = 2h
byte GI_states = c0h
PointDWFixed GVI_origin = {
DWFixed PDF_x = {0.000000}
DWFixed PDF_y = {0.000000}
}
RectDWord GVI_docBounds = {
long RD_left = 0
long RD_top = 0
long RD_right = +480
long RD_bottom = +480
}
PointDWord GVI_increment = {
long PD_x = +20
long PD_y = +15
}
PointWWFixed GVI_scaleFactor = {
WWFixed PF_x = {1.000000}
WWFixed PF_y = {1.000000}
}
ColorQuad GVI_color = {
CQ_redOrIndex = fh, CQ_info = 0h, CQ_green = 0h, CQ_blue = 0h
}
word GVI_attrs = 10h
byte GVI_horizAttrs = 88h
byte GVI_vertAttrs = 88h
byte GVI_inkType = 0h
dword GVI_content = 4710h:0024h
dword GVI_horizLink = 0000h:0000h
dword GVI_vertLink = 0000h:0000h
}
Variable Data:
*** No Variable Data ***
[lesink:0] 11 =>
In addition to printing information about the object at a given address, pobject can print information about certain objects in the application if passed certain flags:
There are more flags available, and it is also possible to ask for more or less instance data information. See the full reference for this command for details.
gentree [<addr>] [<instance field>]
The
gentree
(generic tree) command prints out a generic tree from the given
addr
and
instance field
. The
addr
must be the address of an object in the generic tree, and the
instance field
must be the offset into the Generic master part of the instance chunk or any instance data within the Generic master level which is to be printed. This command is used primarily to ensure correct structure of a generic tree and its instance data and to find a particular object in the generic tree.
The
-i
(implied grab) option is used to find an object by placing the mouse over the window in which the object resides and typing the following:
[hello3:0] 7 => gentree -i
The default address that
gentree
examines is contained in *DS:SI. (See Gentree and Gup
.) To examine objects more closely, pass the handles displayed by
gentree
to the
pobject
command.
vistree [<addr>] [<instance field>]
The
vistree
(visual tree) command prints out a visual tree from the given
addr
and
instance field
. The
addr
must be the address of an object in the visual tree, and the
instance field
must be the offset into the Vis master part of the object's instance data which is to be printed. This command is primarily used to examine the on-screen layout of the application and to ensure correct structure of the visual tree and its instance data. The
vistree
command can use the
-i
option (implied grab), which will use the window that the mouse is over as the first visual object in the printed tree. The default address that
vistree
examines is contained in *DS:DI. To examine objects more closely, pass the handles displayed by
vistree
to the
pobject
command.
gup [<addr>] [<instance field>]
The
gup
(Generic UPward query) command is used to go up the generic tree from a particular object specified by the
addr
argument, the default *DS:SI, or the
-i
option. The
-i
option (implied grab) uses the windowed object under the mouse as the object from which to start the upward query. This command is used primarily to ensure correct generic class hierarchy and to determine the field of the given object.
Swat Display 3-11 Gentree and Gup
(mess1:0) 19 => gentree -i GenViewClass (@5, ^l4340h:0020h) GenValueClass (@6, ^l4340h:0026h) GenValueClass (@7, ^l4340h:0028h) (mess1:0) 20 => gup @5 GenViewClass (@11, ^l4340h:0020h) GenPrimaryClass (@12, ^l4340h:001eh) "MESS #1" GenApplicationClass (@13, ^l41b0h:0024h) *** Is Moniker List *** GenFieldClass (@14, ^l4080h:001eh) GenSystemClass (@15, ^l2460h:0020h) (mess1:0) 21 => gentree ^l4340h:001eh GenPrimaryClass (@16, ^l4340h:001eh) "MESS #1" GenViewClass (@17, ^l4340h:0020h) GenValueClass (@18, ^l4340h:0026h) GenValueClass (@19, ^l4340h:0028h)
vup [<addr>] [<instance field>]
The
vup
(Visual UPward query) command is used to examine the visual ancestors of a particular object given by the
addr
argument, the default *DS:SI, or the
-i
option. The
vup
command can be used with the
-i
option (implied grab) to use the windowed object under the mouse as the object from which to start the upward query. This command is used primarily to ensure correct visual class hierarchy and to determine the field of the given object.
assign, imem
The commands in this group are used to modify memory without detaching Swat and editing the application code. They are often used in conjunction with
istep
,
sstep
, and
pobject
to fix any small errors while the code is executing rather than detaching, modifying the actual code, and recompiling. These fixes are temporary, and you must change the source code to enact the real bug fixes.
assign <addr> <value>
The
assign
command will assign the given
value
to the given
addr
, which can only have type
byte
,
word
, or
dword
. Both memory locations and registers may be assigned new values. This command is used to correct minor mistakes or test differing values at run-time without having to recompile.
imem [<addr>] [<mode>]
The
imem
(inspect memory) command combines examination and modification of memory into one command. It can be used to search through areas of memory and modify problem areas selectively. The command is used to print out memory starting at either the given
addr
or at the default DS:SI in one of the following modes:
There are many subcommands to
imem
which are executed in the same manner as those for
istep
and
sstep
. These subcommands are as follows:
P
subcommand.
assign
command except for singly and doubly quoted strings. A singly quoted string such as `hello' will have its characters entered into memory starting at the current address with no null byte at the end. A doubly quoted string such as "good-bye" will be entered into memory at the current address with the addition of a null byte at the end of the string. This subcommand may not be used in instruction mode.
imem
mode and returns to the command level.
GEOS SDK TechDocs
|
|
5.3 Breakpoints and Code Stepping
|
5.5 Other Important Commands