home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
dumptool.zip
/
DTRACE.ZIP
/
dtrace.doc
next >
Wrap
Text File
|
1998-09-06
|
83KB
|
2,356 lines
DTRACE: Low level Dynamic Trace Utility
Author: Richard Moore
Version: 4.3
Date: 06 Sep 1998
Abstract: Exploits the DosDynamicTrace facility at a low-level. This may be
used to implement ad-hoc tracing in DLLs, Device Drivers, File System Drivers
and the OS2 Kernel. EXE files are also included. Dynamic Trace may be used
for diagnostic purposes and performance monitoring.
DTRACE 3.4a is distributed with Warp 3 fix pack 29 and Warp 4 fix pack 2.
DTRACE 4.2 is distributed with feature F180062 for Warp version 3.
See also:
TRUTILS.ZIP for related trace utilities.
DYNDD.ZIP for a sample Dynamic Trace Device Driver Kernel Exit.
SAMPLRPN.ZIP for sample DTRACE command files that selectively intercept
traps and exceptions.
If you would like to know more about using the OS2 Trace Facility sign up
for the WARP Debug Series - Class 3, developed by the Solution
Developer Operation of IBM. You'll find this on MSE in the USA. It's
also known as P1097 or PS97 in the Education Catalogue.
*****************************************************************************
* *
* R E A D T H I S W A R N I N G *
* *
*WARNING: this is a low level tool that can be used to alter system memory. *
*Incorrect usage of this tool could cause the system damage and unpredictable*
*results, which in an extreme case could cause the loss of data. *
* *
*Dynamic Trace cannot be used at interrupt time or in certain critical *
*parts of the OS2 Kernel (e.g. Dynamic Trace itself). *
*If APAR fix JR09673 is applied to OS2KRNL then dynamic tracing may be made *
*at interrupt time - this should be available in Warp 3 fix pack 30 and *
*Warp 4 fix pack 2. *
* *
*Major codes should be restricted to the range 245-255 so as not to conflict*
*with pre-definied system tracepoints. *
* *
*****************************************************************************
Feedback may be given directly to the author at VM node:
MOORERJ/CROVM3 or INTERNET address: richardj_moorer@uk.ibm.com
Introduction:
------------
Dynamic trace is a facility available within the OS/2 kernel.
Tracepoints are implemented by modifying dynamically code of modules
loaded in memory. This is in contrast to Static tracepoints
which are implemented when applications call the DosSysTrace API.
Dynamic tracepoints are implemented by replacing machine instructions
at specified points within a module by INT3 instructions. This is
done by the DosDynamicTrace API. When the INT3 instruction executes,
control is passed to the system TRAP3 exception handler, which in turn
passes control to Dynamic Trace if the TRAP3 was due to a known
tracepoint. Dynamic Trace interprets instructions, which are in
Reverse Polish Notation, that were passed to it when the trace point
was defined. These instructions allow data to be logged in the system
trace buffer and local variables associated with the tracepoint to be
manipulated. After the RPN instruction stream is complete, the
original instruction is single-stepped then normal execution resumed.
The overhead of dynamic trace is a few milliseconds per tracepoint.
Normally this is small enough not to make a noticeable difference to
system performance.
User Guide:
----------
Command Syntax:
DTRACE APPLY trpgm_file [/h=hmte | /n=name] [/m=major] [/i=id] [/e|/c] [/q] [/d]
DTRACE BUILDTDF trpgm_file [tdf_file] [/m=major] [/n=name] [/i=id] [/q] [/d]
DTRACE REMOVE [trpgm_file | /h=hmte | /n=name] [/c] [/q] [/d]
DTRACE CLEARALL [/q] [/d]
DTRACE QUERY [/h=hmte | /n=name] [/a] [/i=id] [/x[=n]] [/q] [/d]
DTRACE GETVARS [/h=hmte | /n=name] [/i=id] [/v=n:m] [/z] [/r] [/q] [/d]
Numeric values may be specified in hexadecimal or decimal. Hexadecimal
values are signified with either the (C -style) 0x prefix, e.g. 0x2f8;
or the (assembler-style) h suffix, e.g. 2f8h
Optional command line parameters (/i, /m, /h and /n) set defaults which
override the default settings in the header of the trace program file.
Overrides for specific tracepoints take precedence over the command line and
the header in the trace program file.
hmte: module handle (any module with an MTE). May be specified also in
the trace program file.
name: module name.
name may specify a simple name, a name and extension or a
fully qualified name with path information.
If a fully qualified name is specified then it is used without
modification to determine the module handle. If this is unsuccessful
the no attempt is made to search for the module.
For partially specified names DTRACE attempts to work out the
module handle according to the following assumptions:
if a simple name without extension is specified then .DLL is
assumed. If the DLL is not loaded then LIBPATH is used to search
and load the DLL.
All other module types must specify at the very least
name and extension. If the module is not already loaded then
PATH is searched for determine the fully qualified module name
and hence the module handle.
The following types of module may be traced:
Physical Device Drivers
Virtual Device Drivers
File System Drivers
Printer Drivers
Queue Drivers
Custom DLLs (DLLs with non-DLL extension names)
EXE modules
Custom EXE modules (EXEs with a non_EXE extension or no extension)
Base device drivers.
Any of the above in non-PATH or LIBPATH directories.
For BASEDEVs the system records the path name as
being the root directory of the boot drive regardless of which
directory the driver was loaded from. DTRACE will attempt to
derive the module handle of a BASEDEV automatically if only
name and extension are supplied.
Build BUILDTDF may be used for non-DLL modules however under
OS/2 3.0+ JR09872 is required for the TRACE command to process
TDFs for non-DLL modules.
major: The default major code. May also be specified in the trace program
file. Major codes specified with specific tracepoints in the trace
program file override any other specification.
With feature F180062 major codes may range from 1 through 0xffff,
otherwise the kernel will restrict them to the range 1 - 255.
id: Superset grouping of tracepoints. May include more than one major
code. Defaults to 0 when defining tracepoints. NB dynamic trace
generated by TRCUST uses id=0, unless overridden by TDFID=. Id may
be specified also in the trace program file.
Id is intended for use with the QUERY and GETVARS functions.
These functions will assume all non-zero ids are to be processed if
id is not specified.
n:m Variables n to m. Dynamic Trace variables are referred to by index number
starting with 0. Number of variables defined is determined by the
vars= statement of the trace program file.
z: Zero variables.
r: Read variables.
q: Suppress copyright and incidental informational messages.
d: Debugging switch. This is provided for diagnosing problems with DTRACE.
It should only be used at the request of Service personnel.
Note: DTRACE also has associated DTRACE.TDF and TRC0063.TFF files which
permit internal tracing of DTRACE itself by means of TRACE ON DTRACE.EXE
c: Will replace the tracepoints for the module specified it a DTO already exists
in the system.
e: Will merge (APPLY) or de-merge tracepoints for the module if a DTO already exists.
Merge and De-merge are done by matching tracepoint locations.
In the case of merge, the RPN program, major and minor codes are updated for
each tracepoint. The merging ID overrides the previous ID. LOGMAX and VARS are
set to the maximum of the existing and new trace definition.
in the case of de-merge, only those tracepoints that existed previously will be
de-merged. Any others in the de-merging definition will be ignored. LOGMAX and
VARS are maximised as for merge. The new ID overrides the previous ID.
a: Requests dynamic trace definitions for all modules be queried. When /a is not
specified then only those modules that are loaded and have tracepoints in place
will be listed.
x: Requests extended query. /X or /X=1 will cause all tracepoints for the given
module selection to be listed. For each tracepoint the following information is
displayed:
The tracepoint number with in the module.
The major and minor codes for the tracepoint.
The object and offset of the tracepoint location.
The opcode atf the tracepoint location.
The tracepoint status. No status implies the tracepoint has been removed.
Other status shows degrees of initialisation of the tracepoint. Under normal
circumstances this shows a status of "fixed-up, compiled, valid, set". Other settings
are transient or rare states.
Each state has the following meaning:
fixedup The tracepoint location has been resolved to a linear address
compiled The PRN program has been validated
valid The tracepoint is valid for the module
set The tracepoint is installed (INT 3 set in code).
nocode The code for this tracepoint is free
removed The tracepoint has been removed from the code
purged The tracepoint has been purged from a debug alias
calldbg The tracepoint should be handled as an exception
/x=2 will list in addition to the above, the local variable values for each
trace object.
trpgm_file: Trace program file. If a simple name is specified then
an extension of .RPN is assumed.
See below. for the file description.
tdf_fiie: The generated Trace Definition File name. See below.
Options that may also be specified in the trace program file are
overridden when specified on the command line.
DTRACE functions:
APPLY: Insert dynamic tracepoints, specified by the trace program
file for a module specified by name or hmte. A full
description of the trace program file is given below.
BUILDTDF: Build a Trace Definition File (TDF) from the definitions
supplied in the trace program file. The OS/2 TRACE command
may be used subsequently to apply or removed all or selected
tracepoints defined in the TDF.
TFD files must be stored in the current directory, DPATH or
in \OS2\SYSTEM\TRACE.
BUILDTDF permits group and type classifications to be
specified with each tracepoint. These may be used by the
OS/2 TRACE command to select subsets of tracepoints to be
activated. The TRACE command also permits specific minor
codes, or ranges of minor codes to be specified.
The syntax for the TRACE command using a TDF file is as
follows:
TRACE ON|OFF tdf_file
or TRACE ON tdf_file(minor spec)
or TRACE ON tdf_file(group spec)
or TRACE ON tdf_file(type spec)
where:
tdf_file is the file name, excluding path and
extension of the tdf_file.
minor spec is a combination of minor code or
ranges of minor codes separated by commas.
In the following example KERNEL minor codes
(decimal) 1, 2 through 10 and 401 are traced.
TRACE ON KERNEL(1,2-10,401)
group spec is a combination of groups separated by
commas. Each group may further specify one or more
types.
In the following example KERNEL group FS (with
all types) and TK with types PRE and POST is traced.
TRACE ON KERNEL(FS,TK:PRE+POST)
type spec is a combination of types separated by
commas. In the following example all KERNEL PRE and
POST type tracepoints are traced.
TRACE ON KERNEL(PRE,POST)
Notes:
Due to a limitation with the TRACE command, BUILDTDF
can only be used to create TDFs for DLLs and OS2KRNL unless
JR09872 is installed.
If the TRACE command fails to find the TDF in the DPATH it
will look in \OS2\SYSTEM\TRACE\SYSTEM.TDF before looking
finally for \OS2\SYSTEM\TRACE\tdf_file. The becomes an
important consideration when one of the pre-existing system
trace definitions is modified or replaced.
The TRACE command fails to find OS2KRNL.TDF in
in OS2\SYSTEM\TRACE if executed from a command line where
the current directory is other than on the boot drive.
APAR PJ23293 addresses this problem.
See the accompanying TRCTOOLS documentation for further
information of modifying and replacing system trace
definitions.
REMOVE: Remove dynamic tracepoints for a module specified by name or
handle.
CLEARALL: Remove all dynamic tracepoints for all modules.
QUERY: Query by id or hmte all traced modules, their ids and number
of Dynamic Trace variables.
Unless /i /n or /h is specified all zero and non-zero Ids
are queried for active modules only. To query inactive modules
in addition, /a must be specified.
Note: Standard system dynamic trace definitions and user
definitions that are defined using TRCUST are always defined
with id=0.
GETVARS: Retrieve and/or set to zero the Dynamic Trace variables for
a given id or module.
By default all variables of all non-zero ids are retrieved.
Variables are displayed as a list in hexadecimal and decimal
formats.
Format of the Trace Program File:
This file specifies one or more tracepoints for a module. Each
tracepoint may have an associated program that species to DynamicTrace
what variables to manipulate and what data to log in the system trace
buffer when the tracepoint fires.
Comments may appear after the instructions or on whole lines. They
are prefixed with a semi-colon.
Blank, tab, bell and basckspace characters are ignored by DTRACE.
LF, CR, VT delimit a line.
Null lines are ignored.
The trace program consists of a header followed by one or more tracepoint
definitions. Each tracepoint definition has a header followed by an
optional program specified as a sequence of Reverse Polish Notation
instructions. The RPN commands use a circular stack of 16 double-word
elements as a work space. The top element of the stack is the only
immediately accessible element. As each element is accessed the top
of stack (TOS) pointer is moved to point to the preceding stack
element - this is referred to as a POP operation even though the
popped stack element is not actually removed from the stack. Thus an
RPN command that takes two stack parameters pops the two topmost
elements from the stack. Whenever data on the stack is referenced it
is done so in integral numbers of elements. Thus pushing or popping a
word will move the stack pointer as if a double-word had been pushed
or popped. Word and byte length data is always padded to a double-word
when pushed on to the stack.
The trace program may be used for three purposes (which may be
combined):
1) To cause one or more items of data to be logged in the system
trace buffer.
2) To update local variables which are associated with a particular
module being traced.
3) To detect a specific condition (value of a register, value in
memory or code path) and force a System Dump when that condition
occurs.
NB: this function is not available in all releases of OS/2.
The entire set of trace definitions and local variables for a
particular module is referred to as a Dynamic Trace Object (DTO).
One DTO may exist per module. DosDynamicTrace will not merge an
existing DTO with additional definitions for the same module.
DTOs for several modules may be grouped under the same id - see
the /i parameter above and the id= parameter below.
RPN command syntax rules are as follows:
[label:] operator [operand1 [,operand2 [, ..... ]]] [; comment]
[;comment]
Where:
label
is an optional string of 1 - 255 characters, excluding ':',
initiated with a non-numeric character and delimited by a ':'.
A label must always precede a command, but the command my be
coded on the following line. Labels are for use by the jump
instructions as an alternative to coding an explicit numeric
value. Backward jumping is not permitted.
operator
is one of the valid RPN commands listed below.
operand1,...
are operands as defined by each RPN command.
A comment is initiated by a ';' and may follow on the same line as a
command or on a new line.
RPN commands,labels and operators are case insensitive.
Imbedded blanks are ignored.
Data logged by DTRACE may be formatted using TRACEFMT. The format will be
in hexadecimal bytes unless a custom trace format file has been generated
using the TRCUST utility. When using TRCUST, specify the TP parameter as
@STATIC. The prefixes %P and %R may be used. See the OS/2 Debugging
Handbook (SBOF-8617), the OS2PDP PACKAGE or the DDK for TRCUST.
The TRSPOOL utility may be used to capture trace data on disk files.
See TRSPOOL PACKAGE on OS2TOOLS or in the OS/2 Debugging Handbook
(SBOF-8617).
Refer to the OS/2 Debugging Handbook, Volume 1 and 3 for further information
on the system trace utility.
File header:
------------
Zero or more of the following may be specified, in any order:
vars= Number of Dynamic Trace variables to be defined
(initialised to zero).
major= Major code
hmte= Module handle
id= DTO grouping id - not to be confused with typedef or
groupdef ids. This is a gouping of Dynamic Trace Objects.
The default DTO id is 0. Id is used with GETVARS and QUERY
functions.
logmax= Maximum data to be logged in the trace buffer (default 512
bytes).
With feature f180062 the maximum value for logmax is
4099, prior to that the maximum was 512. Note: TRCUST
allows a maximum of 4096 to be specified by MAXDATALENGTH or
the length parameter of memory logging parameters. Internally
the maximum log size will be increased by 3 to allow for the
3 byte memory logging prefix. DTRACE on the other hand operates
at a lower level and the value specified by logmax is presented
to the system unedited.
name= Module name. See name specification above.
typedef= Defines a type keyword. This is used only by the BUILDTDF
function. The definition is specified as:
typedef=keyword,id.
Keyword is a string, which is used by type statements, see
below.
id is a value equal to a power of two in the range 2**1 to
2**31.
Multiple typedef statements my be specified.
groupdef= Defines a group keyword. This is used only by the BUILDTDF
function. The definition is specified as:
groupdef=keyword,id.
Keyword is a string, which is used by group statements, see
below.
id is a value in the range 0x to 0xffffffff.
Multiple groupdef statements my be specified.
Major code and hmte are required but may be specified or overridden by
the command line parameters.
If name and hmte are specified then the first parameter encountered
takes precedence.
id defaults to zero.
vars defaults to zero.
logmax defaults to 512.
The BUILDTDF function requires all definitions to be
completely specified within the trace program file. Furthermore
name must be specified rather than a module's hmte.
Tracepoint header:
------------------
The following must be specified, in any order, with the
exception that minor= must appear first.
minor= Tracepoint minor code
major= Tracepoint major code - this may be respecified for
each tracepoint and overrides the major code specified
in the file header. This applies to which the current
tracepoint.
opcode= Byte of opcode in module where the tracepoint will be
inserted. Not all instructions are allowed to be
specified as tracepoints, in particular the following
are prohibited:
int3, int3, int, into, bound, mul, imul, div, and idiv
which have opcodes:
0xcc, 0xc3, 0xcd, 0xce, 0x62, 0x69, 0x6b, and
0xf6nn and 0xf7nn when nn is ??1?????.
Note: if an instruction has a prefix then the tracepoint must
be applied to the prefix and not the following byte. If this
is not observed then the effect of the prefix will be lost when
the instruction executes.
object= Relative object of module where trace point will be
applied. Objects are numbered from 1.
offset= Offset within object where tracepoint will be applied.
major= The major code override for a specific tracepoint. The
default major code must be specified in the header to the
trace program file.
type= Type is an optional parameter that is used only by the
BUILDTDF function. Its purpose is to associate with each
tracepoint one or more types. These are used by the
OS/2 TRACE command as a means of selecting a subset of the
tracepoints defined in the generated TDF. The operand to the
type= statement is be specified as a sequence of one or more
keyword names defined by typedef statements, separated
'+' signs as follows:
type=[keyword1[+keyword2 ...]]
A typical use of the trace type is to associate a particular
tracepoint with a particular characteristic. For example,
tracepoints in DOSCALL1 and KERNEL use type=PRE for API
pre-invocation tracepoints and type=POST for
API post-invocation tracepoints.
Only one type statement is permissible per tracepoint.
group= Group is an optional parameter that is used only by the
BUILDTDF function. Its purpose is to associate related
subsets of the set of tracepoints defined in the generated
TDF. These are used by the OS/2 TRACE command as a means of
selecting a subset of the tracepoints defined in the
generated TDF. The operand to the group= statement is
specified as a single keyword name that has been defined by
the groupdef statements.
A typical use of the trace group is to associate all
tracepoints that relate to a particular component of the
system. For example, the group FS is used to associate all
tracepionts in DOSCALL1 and KERNEL that relate to the
file-system.
Group is intended to be an exclusive classification of
tracepoints compared with Type. Only one group may be
associated with a particular tracepoint, whereas a
tracepoint may have several type.
Only one group statement is permissible per tracepoint.
The Trace Program
-----------------
Trace program may specify any meaningful combination of the following
RPN instructions. (TOS = Top of Stack).
Leng Mnem Operand(s) Description
-th -onic
Bytes
---------------------------------------------------------------------
1 Abort Abort - Log No Information
1 Add Add top 2 DWORD stack elements
1 Cnvrt DXS Convert Dword to Segmented
1 Cnvrt FXS Convert Flat to Segmented
1 Cnvrt SXD Convert Segmented to Dword
1 Cnvrt SXF Convert Segmented to Flat
3 Inc V,word Increment Immediate Variable
1 Inc VIi Increment indexed Variable
3 Jmp N,word Jump forward N bytes or to a label
3 Jmp NN,word Jump forward N bytes or to a label if TOS < 0
3 Jmp PN,word Jump forward N bytes or to a label if TOS > 0
3 Jmp ZN,word Jump forward N bytes or to a label if TOS = 0
1 Log ARF Log ASCIIZ at Flat Range
1 Log ARS Log ASCIIZ at Segmented Range
2 Log DN,byte Log N DWORDs
1 Log MRF Log Memory at Flat Range
1 Log MRS Log Memory at Segmented Range
2 Log WN,byte Log N WORDs
3 Move V,word Move top of stack to Immediate Var.
1 Move VIi Move top of stack to indexed Var.
1 Mul Multiply top 2 stack elements
3 Or V,word OR immed. indexed variable with TOS
2 Pop N,byte Rotate stack down (pop) N times
1 Push CS Push contents of (CS)
5 Push D,dword Push DWORD Immediate
1 Push DS Push contents of (DS)
1 Push EAX Push contents of (EAX)
1 Push EBP Push contents of (EBP)
1 Push EBX Push contents of (EBX)
1 Push ECX Push contents of (ECX)
1 Push EDI Push contents of (EDI)
1 Push EDX Push contents of (EDX)
1 Push EFlags Push contents of (EFlags)
1 Push EIP Push contents of (EIP)
1 Push ES Push contents of (ES)
1 Push ESI Push contents of (ESI)
1 Push ESP Push contents of (ESP)
1 Push FIF Push Flat Indirect Flat
1 Push FS Push contents of (FS)
1 Push GS Push contents of (GS)
5 Push OXF,dword Push (DWORD Object to Flat Address)
2 Push OXS,byte Push (Object to Selector)
1 Push SIS Push Segmented Indirect Segmented
1 Push SS Push contents of (SS)
3 Push V,word Push Immediate Variable
1 Push VIi Push indexed Variable
3 Push W,word Push WORD Immediate
1 Push WIS Push WORD Indirect Segmented
1 Remove Remove the current tracepoint
1 Sub Subtract top 2 stack elements
1 SysDump Force a system Dump (*)
1 And AND top 2 stack elements (*)
1 Or OR top 2 stack elements (*)
1 Xor XOR top 2 stack elements (*)
1 Neg 1's complement TOS (*)
1 Exit Log data and exit tracepoint (*)
3 SetMin W,word Override the tracepoint minor code with 'word' (**)
1 SetMin Override the tracepoint minor code from TOS (**)
3 SetMaj W,word Override the tracepoint major code with 'word' (**)
1 SetMaj Override the tracepoint major code from TOS (**)
1 Xchg Swap top two elements on the stack. (**)
Recovery may not be possible.
1 Call KDB (df) Force immediate entry to the kernel debugger
1 Call DD (f) Call any device drivers registered for Dynamic Trace Kernel Exits (***)
1 Call DBG (f) Generic debugger call. If the application is being debugged by
an applicaiton debugger, this command will force entry as if a
trap had occurred. If no application debugger is active and
the traced module is running under the debug kernel then
entry to the kernel debugger will be forced. If entry to
the kernel debugger is desired in preference to an application
debugger then the .O kernel debugger command must be used.
Having entered the kernel debugger, the user may use G to
continue execution.
Where TRAPDUMP is defined in the system and neither the
debug kernel, an application debugger or application
exception handler continues execution then a system dump
will be take.
Once Call DBG is executed the tracepoint is disabled and
the original instruction is restored.
2 Dup N,byte (f) Duplicate the TOS N times.
1 Dup (f) Pop a double word for duplication, and then a duplication
count from the TOS and push the duplicand N+1 times.
1 Enter BIF (fd) Pop a byte from TOS then a flat address and store the byte
at that address.
1 Enter WIF (fd) Pop a word from TOS then a flat address and store the word
at that address.
1 Enter DIF (fd) Pop a double-word from TOS then a flat address and store the
double-word at that address.
1 Enter BIS (fd) Pop a byte from the TOS, then an offset, then a selector and
store a byte at the 16:16 segmented address.
1 Enter WIS (fd) Pop a word from the TOS, then an offset, then a selector and
store a word at the 16:16 segmented address.
1 Enter DIS (fd) Pop a double-word from the TOS, then an offset, then a selector and
store a double-word at the 16:16 segmented address.
1 Push BIF (f) Pops a flat address from the TOS then pushes a byte at that address.
1 Push BIS (f) Pops an offset then a segment from the TOS then pushes a byte at
that 16:16 address.
1 Push DIS (f) Pops an offset then a segment from the TOS then pushes a
double-word at that 16:16 address.
1 Push WIF (f) Pops a flat address from the TOS then pushes a word at that address.
1 Push TSC (fp) Pushes the Pentium TSC high double-word then low-double word onto
onto the TOS. On non-pentium systems, zero is stored.
1 Push TID (f) Pushes the current Thread Ordinal on to the TOS
1 Push PID (f) Pushes the current Process Id onto the TOS.
1 Push PROCID (fs) Pushes the current Processor ID onto the TOS. Zero is stored for
Uni-processor systems.
1 Push SLOT (f) Pushes the current thread slot number onto the TOS.
1 Push pTCB (f) Pushes the flat address of the current TCB to TOS.
1 Push pPTDA (f) Pushes the flat address of the current PTDA to TOS.
1 Push pPCB (fs) Pushes the flat address of the current PCB to TOS. Zero is store
on Uni-processor systems.
1 Suspend (f) Suspends system trace recording.
1 Resume (f) Resume system trace recording.
2 Rol N (f) Rotate TOS left N bits.
2 Ror N (f) Rotate TOS right N bits.
2 Shl N (f) Shift TOS left N bits.
2 Shr N (f) Shift TOS right N bits.
1 Rol (f) Pops a double-word then a count from TOS then rotates
the double word left N bits and replaces it on the TOS.
1 Ror (f) Pops a double-word then a count from TOS then rotates
the double word right N bits and replaces it on the TOS.
1 Shl (f) Pops a double-word then a count from TOS then shifts
the double word left N bits and replaces it on the TOS.
1 Shr (f) Pops a double-word then a count from TOS then shifts
the double word right N bits and replaces it on the TOS.
1 Vfa (f) Pops a flat address from the TOS.
Verifies read access to a byte pointed to by the flat
address. The TOS is replace by a 0 if access is given
and by 1 if not.
1 Vsa (f) Pops and offset then a selector from the TOS.
Verifies read access to a byte pointed to by the 16:16
address. The TOS is replace by a 0 if access is given
and by 1 if not.
1 Push KEAX (f) If in the kernel, (Kmode) pushes the client EAX otherwise current EAX
1 Push KECX (f) If in the kernel, (Kmode) pushes the client ECX otherwise current ECX
1 Push KEDX (f) If in the kernel, (Kmode) pushes the client EDX otherwise current EDX
1 Push KEBX (f) If in the kernel, (Kmode) pushes the client EBX otherwise current EBX
1 Push KESP (f) If in the kernel, (Kmode) pushes the client ESP otherwise current ESP
1 Push KEBP (f) If in the kernel, (Kmode) pushes the client EBP otherwise current EBP
1 Push KESI (f) If in the kernel, (Kmode) pushes the client ESI otherwise current ESI
1 Push KEDI (f) If in the kernel, (Kmode) pushes the client EDI otherwise current EDI
1 Push KES (f) If in the kernel, (Kmode) pushes the client ES otherwise current ES
1 Push KCS (f) If in the kernel, (Kmode) pushes the client CS otherwise current CS
1 Push KSS (f) If in the kernel, (Kmode) pushes the client SS otherwise current SS
1 Push KDS (f) If in the kernel, (Kmode) pushes the client DS otherwise current DS
1 Push KEFLAG (f) If in the kernel, (Kmode) pushes the client EFLAG otherwise current EFLAG
1 Push KEIP (f) If in the kernel, (Kmode) pushes the client EIP otherwise current EIP
1 Push KFS (f) If in the kernel, (Kmode) pushes the client FS otherwise current FS
1 Push KGS (f) If in the kernel, (Kmode) pushes the client GS otherwise current GS
1 Enter EAX (fd) Pops a double-word from the TOS and modifies the current EAX.
1 Enter EBX (fd) Pops a double-word from the TOS and modifies the current EBX.
1 Enter ECX (fd) Pops a double-word from the TOS and modifies the current ECX.
1 Enter EDX (fd) Pops a double-word from the TOS and modifies the current EDX.
1 Enter ESI (fd) Pops a double-word from the TOS and modifies the current ESI.
1 Enter EDI (fd) Pops a double-word from the TOS and modifies the current EDI.
1 Enter EBP (fd) Pops a double-word from the TOS and modifies the current EBP.
1 Enter DS (fd) Pops a double-word from the TOS and modifies the current DS.
1 Enter ES (fd) Pops a double-word from the TOS and modifies the current ES.
1 Enter FS (fd) Pops a double-word from the TOS and modifies the current FS.
1 Enter GS (fd) Pops a double-word from the TOS and modifies the current GS.
1 Push CR0 (f) Pushes CR0 onto the TOS.
1 Push CR2 (f) Pushes CR2 onto the TOS.
1 Push CR3 (f) Pushes CR3 onto the TOS.
1 Push CR4 (f) Pushes CR4 onto the TOS.
1 Push DR0 (f) Pushes DR0 onto the TOS.
1 Push DR1 (f) Pushes DR1 onto the TOS.
1 Push DR2 (f) Pushes DR2 onto the TOS.
1 Push DR3 (f) Pushes DR3 onto the TOS.
1 Push DR6 (f) Pushes DR6 onto the TOS.
1 Push DR7 (f) Pushes DR7 onto the TOS.
1 Push TR (f) Pushes TR onto the TOS.
1 Push LDTR (f) Pushes LDTR onto the TOS.
1 Push GDTR (f) Pushes GDTR FWORD onto the top two stack elements.
1 Push IDTR (f) Pushes GDTR FWORD onto the TOS two stack elements.
1 Push MSR (fp) Pops a MSR register number from the TOS then pushes the high then low
double-words of the MSR onto the stack.
1 Push PMC (fp) Pops a PMC counter number from the TOS then pushes the high then low
double-words of the PMC onto the stack.
1 Push CPUID (fp) Pops a CPUID information number from the TOS then pushes the four
double-words of the CPUID, highest first, onto the stack.
* Each of the commands flagged with (*) require APAR PJ22196 applying
to the OS2KRNL.
* Each of the commands flagged with (**) will be supported the GA version
of OS/2 Warp 4.0 - they are not implemented in the public beta version.
* Each of the command flagged with (f) require feature F180062 to be installed.
* Each of the command flagged with (d) operate only under the debug kernel and
no-op on the retail kernel.
* Each of the command flagged with (s) operate only under SMP and no-op
otherwise.
* Each of the command flagged with (p) operate only under certain Pentium
processors and no-op, otherwise.
Each of these commands acts as follows:
PUSH: Push a value on to the RPN stack
In Push SS and Push ESP the value of SS and ESP is dependent on whether the
tracepoint occurred at ring 0 or not.
In Push EIP, the EIP on the stack is one too large, due to the
INT3.
Push W takes a word operand, zero extends it, and pushes
it on to the RPN stack.
Push OXS converts its byte operand into a selector,
zero extends that value, and pushes it on to the stack.
The byte operand is on object number of the module which
is currenlty being traced.
Because MTEs may eventually become nonresident, the selectors
(up to 256) are stored in an array by DynamicTrace when the tracepoints
were inserted. The word operand indexes this array to get the sel.
Push WIS pops an offset, then a selector, from the RPN stack,
fetches the user word at that 16:16 address, zero extends it,
and pushes that on to the RPN stack.
If the address is invalid or not present, a GP fault or Page
fault record will be logged in the buffer, and the interpreter
will exit.
Push SIS pops an offset, then a selector, from the RPN stack,
fetches the user dword at that 16:16 address and pushes that on to
the RPN stack in the segmented address format. That is,
the high word (selector) is zero extended and pushed, and then
the low word (offset) is zero extended and pushed.
If the address is invalid or not present, a GP fault or Page
fault record will be logged in the buffer, and the interpreter
will exit.
Push OXF converts its dword operand into a flat address,
and pushes that on to the stack. See description of PUSH OXS for
more details.
Push FIF pops a Dword from the RPN stack, and then
pushes the dword at that flat address on to the stack.
Push V takes a word operand. Push V uses that to index
to the Dynamic Trace variable in the current DTO, and pushes the value
it finds there.
Push VIi fetches an index of a Dynamic Trace variable from
the top of the stack, (without doing a pop), and then
pushes the value of that variable on to the stack.
LOG: Log data in the system trace buffer.
Log WN takes a byte operand, and repeats the following operation
that many times:
Pop the value from the top of the RPN stack
Log the low word of that value, ignoring the high word.
If the log overflows, the interpreter will exit without continuing,
but will record as much as it can.
Log MRS pops the following from the RPN stack:
Offset
Selector
Length
Log MRS then zero extends all these values, and attempts to
move Length number of bytes from the given 16:16 address into
the log buffer.
The logged memory is prefixed by 3 bytes :
Token byte of 0,
Length word (length of logged information, in bytes)
If an address is invalid or not present, a GP fault or Page
fault record will be logged in the buffer, and the interpreter
will exit.
If the log overflows, the interpreter will exit without continuing,
and without logging the memory.
Log ARS pops the following from the RPN stack:
Offset
Selector
Length
Log ARS then zero extends all these values, and attempts to
move Length number of bytes from the given 16:16 address into
the log buffer. The data transfer will be discontinued if a
null byte is fetched. The null byte will not be logged.
The logged string is prefixed by 3 bytes :
Token byte of 1,
Length word (length of logged information, in bytes)
If an address is invalid or not present, a GP fault or Page
fault record will be logged in the buffer, and the interpreter
will exit.
If the log overflows, the interpreter will exit without continuing,
and without logging the string.
Log DN takes a byte operand, and repeats the following operation
that many times:
Pop the value from the top of the RPN stack
Log the value (as a DWORD)
If the log overflows, the interpreter will exit without continuing,
but will record as much as it can.
Log MRF pops the following from the RPN stack:
Flat Address
Length
Log MRF then zero extends the length, and attempts to move
Length number of bytes from the given flat address into
the log buffer.
The logged memory is prefixed by 3 bytes :
Token byte of 0,
Length word (length of logged information, in bytes)
If an address is not present, a Page fault record will be
logged in the buffer, and the interpreter will exit.
If the log overflows, the interpreter will exit without continuing,
and without logging the memory.
Log ARF pops the following from the RPN stack:
Flat Address
Length
Log ARF then zero extends the length, and attempts to move
Length number of bytes from the given flat address into
the log buffer. The data transfer will be discontinued if a
null byte is fetched. The null byte will not be logged.
The logged string is prefixed by 3 bytes :
Token byte of 1,
Length word (length of logged information, in bytes)
If an address is not present, a Page fault record will be
logged in the buffer, and the interpreter will exit.
If the log overflows, the interpreter will exit without continuing,
and without logging the string.
When memory references are invalid the token byte is set to one of
the following to indicate the type of error encountered:
-1 Invalid Selector
-2 Selector not Present
-3 Page not Present
The byte count is set to 4 and the data logged is the fault
address.
ADD/SUB/MUL/AND/OR/XOR: Add/Subtact/Multiply the top two stack
elements
Add pops two DWORDs from the RPN stack, and pushes their sum.
Sub pops two DWORDs from the RPN stack, and pushes their
difference. The first value popped is subtracted from the second.
Mul pops two DWORDs from the RPN stack, and pushes their
product.
And pops two DWORDs from the RPN stack, and pushes their
bit-wise AND.
Or pops two DWORDs from the RPN stack, and pushes their
bit-wise Or.
Xor pops two DWORDs from the RPN stack, and pushes their
bit-wise Xor.
NEG: 1's complement top of stack.
Neg 1's complements the TOS. No data is pushed or popped.
CNVRT: Convert an address
Cnvrt FXS pops a dword from the RPN stack, uses CRMA
to translate that flat pointer to a 16:16 segmented pointer.
It then pushes the selector (zero extended) and then the
offset (zero extended) on to the stack.
If the flat address does not lie within the compatibility
region, the interpreter will exit immediately.
Cnvrt SXF pops a selector, then an offset from the RPN stack,
uses CRMA to translate that 16:16 pointer to a flat address,
and pushes that flat address on to the stack.
If the segmented address does not lie within the comparability
region (GDT selector), the interpreter will exit immediately.
Cnvrt DXS pops a DWORD, then pushes the high word (zero
extended) and then the low word (zero extended). No CRMA is
applied.
Cnvrt SXD pops a low word, then a high word, then
concatenates them into a DWORD, and pushes the result.
POP: Pop a value from the RPN stack.
Pop N takes a byte operand, and pops that many operands
from the stack. As the values are not actually removed from
the 16-element circular stack, Pop N effectively rotates
the stack down.
MOVE: Move a value to a variable.
Move V takes a word operand. Move V then moves
the value on the top of the stack to the Dynamic Trace variable
in the current DTO at that index. The top of stack pointer
is not changed.
Move VIi pops a variable index off the top of the stack,
and then pops a value off the top of the stack. The value is moved
into the Dynamic Trace variable in the current DTO at that index.
The variable and the index are then pushed back on to the stack,
so that there is no net change on the stack at all.
If the index is too large, the interpreter will exit with an error.
INC: Increment a variable.
Inc V takes a word operand, and increments the value in the
Dynamic Trace variable in the current DTO at that index.
Inc VIi fetches an index of a Dynamic Trace variable from
the top of the stack, (without doing a pop), and then
increments the value of that variable.
If the index is too large, the interpreter will exit with an error.
JMP: Jump forward in the RPN program.
Jmp takes a word or label as operand. Jmp causes an
unconditional jump forward in the instruction stream by
that number of bytes, relative to the first byte of the next
instruction.
Therefore, Jmp by 0 bytes is a NOP (i.e jmp n,0)
Jmp ZN takes a word or label as operand. Jmp ZN causes an
unconditional jump forward in the instruction stream by
that number of bytes, relative to the end of the instruction,
but only if the value on the top of the stack is zero.
Jmp NN takes a word or label operand. JmpNN causes an
unconditional jump forward in the instruction stream by
that number of bytes, relative to the end of the instruction,
but only if the value on the top of the stack is negative.
Jmp PN takes a word or label operand. Jmp PN causes an
unconditional jump forward in the instruction stream by
that number of bytes, relative to the end of the instruction,
but only if the value on the top of the stack is positive.
To prevent loops, no backward jumps are permitted. Also, it is
illegal to jump into the code stream for another tracepoint.
If labels are specified, DTRACE calculates the relative forward
offset.
REMOVE: Remove and Abort the current tracepoint.
ABORT: Abort the tracepoint.
Abort aborts the tracepoint entirely. The interpreter
exits, but does not log any information. The data logged
by this tracepoint is lost.
However, alterations to the variables remain.
By using Abort in combination with the Jmp
instructions, unnecessary tracepoints can be filtered
at run time, without crowding or overflowing the log buffer.
EXIT: Exit the tracepoint.
Exit terminates the tracepoint. The interpreter
exits, and logs any information requested so far. The tracepoint
remains in tact.
By using Exit in combination with the Jmp
instructions, specific conditions can be detected before logging
additional data.
If Exit is not available (systems without PJ22196) then the
equivalent may be achieved by coding:
jmp n,exit
.
.
.
.
exit: jmp n,0 ;nop
ORV: OR a Dynamic Trace variable with TOS.
SYSDUMP: Force a System Dump.
SysDump transfers control to the stand alone dump process. No
data is logged. No system shutdown is performed and normal
system execution is terminated immediately.
Use this command with the Jmp instructions to detect illusive error
conditions that require dump analysis at the point of error.
SETMAJ: Override the tracepoint major code
SetMaj takes the word value from the TSO to override the tracepoint
major code. The override remains in effect until the current RPN
program exits. Since data is not logged to the system trace buffer
until the RPN program exits, the major code may be overridden at any
point and remain effective for the whole trace entry.
SetMaj may be specified with the W,word operand form. In this case
'word' forms the major code override.
Note: Prior to feature F180062 the system trace facility admits only
major codes from 0 - 255. Any specification of a major code greater
than 255 will be treated as if the high-order byte value is zero. With
F180062 the allowable range will be from 0-65535.
This is provided to allow trace formatting templates to be
selected dynamically according to the data logged.
SETMIN: Override the tracepoint minor code
SetMin takes the word value from the TOS to override the tracepoint
minor code. The override remains in effect until the current RPN
program exits. Since data is not logged to the system trace buffer
until the RPN program exits, the minor code may be overridden at
any point and remain effective for the whole trace entry.
SetMin may be specified with the W,word operand form. In this case
'word' forms the minor code override.
The system trace facility admit minor codes in the range from
0x0000 to 0xffff.
This is provided to allow trace formatting templates to be
selected dynamically according to the data logged.
XCHG: Exchange the top two entries on the RPN Stack.
Xchg pops the top two stack elements then pushes them back on to
the stack in the reverse order.
ENTER: Alter memory or a register value. See Push
CALL: Exit to another facility.
CALL KDB forces immediate entry to the kernel debugger by means of a
simulated TRAP 3. On uniprocessor kernels, execution may be continued
by using the G Kernel Debugger command, but any attempt to single-step
(T or P) or go from a particular address (T= or G=, or P=) may cause a
system failure.
Under SMP kernels, recovery is generally not possible.
Use CALL KDB only if you wish to force entry to the kernel debugger
immediately rather than let normal trap processing determine how a
TRAP 3 should be handled.
CALL DBG is a generic call to a debugging facility. Depending on
circumstance this could be: System Dump, Process Dump, Kernel Debugger
or Application Debugger.
CALL DBG removes the tracepoint and restores the original instruction.
It then exits the Dynamic Trace facility via TRAPCommonFaultEntry.
The effect of this is to simulate a trap 3 as if a real INT3 instruction
had been coded in the trace code path, with the exception that the INT3
is no longer in the code path. In essence CALL DBG inserts a temporary
breakpoint into the traced code path but removes it as soon as it fires.
If the breakpoint is intercepted by a debugger then execution may be
continued as if a regular breakpoint had been activated. If debuggers are
not active then dump processing may take effect if customised to do so.
If no debuggers are active and no dump processing is specified then
the application will receive a breakpoint exception. If it has exception
handlers designed to handle this, it may recover otherwise it will be
terminated.
CALL DD allow dynamic trace device driver exits to be called as an
extension to the RPN command set. Each driver exit is called in the
order they were registered. They have access to and may modify
the current log buffer, RPN Stack, Major and Minor codes. They may
call SysTrace directly using DevHlp_RAS (DevHlp_SysTrace) to write
additional trace records. Exits are also able to register a temporary
fault handler address to allow them the recover from General Protection
and Page faults from data accesses. Stack faults and other exceptions
are not recoverable.
A device driver registers a Dynamic Trace Exit using the
DevHlp_RegisterKrnlExit (dl = 6fh). This interface requires
BX:SI to point to the exit address, AX the be the function code
(0000h = delete, 1000h = add, 2000h = query) and CX = 0003h (DYN_Exit).
Registration may take place at device driver initialisation time.
On entry to the device driver's exit routine FS:DI points to a ddx_s
structure, defined . AX contains the driver's data segment and DS the
FLAT 32-bit 4Gb data selector.
The driver may modify ddx_StackIndex if it wishes to reposition the
current RPN stack pointer.
The RPN stack may be modified. The Head of the stack is pointed to by
ddx_StackStart. Each stack element is a DWORD. ddx_StackIndex indexes,
by DWORD into the stack. The maximum number of stack elements are given
in ddx_StackSize. The action of pushing onto the stack increments the
stack index by 1 modulo ddx_StackSize. Conversely popping decrements
ddx_StackIndex module ddx_StackSize.
ddx_Major and ddx_Minor may be modified.
The Driver may write to the log pointed to by ddx_LogStart, but must
update ddx_LogIndex to point to the next available byte in the Log buffer
if new data is to be written or data removed. If data remains in the log
buffer on normal completion of the current RPN program it will be written
to the trace buffer as a single trace record. Therefore, the format of
data in the log buffer is only required to conform with any TFF require to
format it. The number of bytes written must not exceed ddx_LogSize.
All pointers are 16:16 far pointers (i.e. ddx_LogStart and ddx_StackStart)
The driver is called as if at interrupt time and is consequently restricted
to the number of DevHlps available. DevHlp_SysTrace (DevHlp_RAS) may be used
to log additional data instead of adding data to the original log buffer
pointed to by ddx_LogStart. This provides a means of logging more than
512 bytes per tracepoint. It DevHlp_SysTrace is called
then any trace record created by the current RPN program will follow
chronologically from the static trace records created by the driver.
While the major and minor codes used by the dynamic tracepoint might exceed
255, DevHlp_SysTrace is currently restricted to maximum major and minor
code values of 255. Attempts to use a higher value will result in it being
truncated to a single byte.
Dynamic Tracepoints may not be placed in the Driver's exit code.
The Device Driver may register a fault handler to receive control for
data access exceptions causing Faults 13 (General Protection) and 14
(Page Fault). This is done by placing the 16:16 address of the fault handler
in ddx_pfnFault. When an exception occurs, dynamic trace will give control to
the fault handler, having first disabled it. The driver may subsequently enable
the fault handler by setting ddx_pfnFault. On entry to the fault handler AX
contains the driver's data segment. DS, ES, SS and ESP are destroyed.
Other segment and general registers retain values from the point the fault
occurred. If the driver does not register a fault handler then the
tracepoint is aborted if a fault occurs within the driver.
SS, SP, DS, FS and DI must be restored by the driver on exit.
The driver returns to the system using a far16 return.
On exit, if EAX is zero then the next registered driver will be called
otherwise control returns to Dynamic Trace.
The driver exit runs as an extension to the system's trap 3 handler. No
INT3 instructions may occur in the exit code path. Nor may the Kernel
debugger BP, T or P commands be used. Breakpoints may be set using
BR, but must be disabled before continuing execution.
G <to address> may not be used if the target address lies within the
trap 3 code path and in particular the device driver exit code path.
Traps other than 1 and 3 may be intercepted using VT. Always use
VC following entry to the kernel debugger after a vector trap.
These restrictions apply because the commands list employ temporary INT3
breakpoints as part of their mechanism.
The structure definition for the DDX is as follows:
struct ddx_s {
unsigned long ddx_StackStart;
unsigned long ddx_StackSize;
unsigned long ddx_StackIndex;
unsigned long ddx_Major;
unsigned long ddx_Minor;
unsigned long ddx_LogStart;
unsigned long ddx_LogSize;
unsigned long ddx_LogIndex;
unsigned long ddx_pfnFault;
};
DUP/DUPN
Causes the element at the TOS to be duplicated N time. In the case of DUP N
the duplication count is immediate. With DUP the count is popped from the TOS
following the duplicand. The duplicand is immediately popped back onto the stack
before any duplication is performed.
ROL/ROR/SHL/SHR/ROLN/RORN/SHLN/SHRN
Causes the element at the TOS to be rotated or shifted N times. In the case of xxxN
the shift/rotation count is immediate, otherwise it is popped from the TOS following
the element to be shifted/rotated.
----------------------------------------------------------------------
Invalid Data - return code 13 errors
Return code 13 is issued for a variety of reasons from the DosDynamicTrace API.
However the majority potential reasons are caught by DTRACE before the API
call is made and an explanatory message is issued. The remaining cases that
cause DosDynamicTrace to return ERROR_INVALID_DATA are:
1) Variables out of range. An RPN command references an undefined local variable or
the GETVARS function references undefined local variables.
2) Logmax exceeds the maximum value currently implemented by system trace. The maximum
prior to f180062 was 512. With feature f180062 this has been increased to 4099.
3) Major exceed the maximum value currently implemented by system trace. Prior to
feature f180062 (Warp 3.0 fix pack 34) the maximum value is 255 (0xff). With feature
f180062 the maximum value allowed is 65535 (0xffff).
4) Opcode does not match that at the specified object and offset.
This could imply that the hmte is incorrect.
5) The object and offset are not defined within the specified module.
This could imply that the hmte is incorrect.
6) Opcode specifies a prohibited instruction. These are:
int3, int, into, bound, mul, imul, div, and idiv
0xcc, 0xcd, 0xce, 0x62, 0x69, 0x6b, 0xf6nn and 0xf7nn when nn is ??1?????.
Version 4.3 of DTRACE checks for prohibited opcodes where possible. If an one
is found DTRACE raises an error. If a tracepoints falls on an instruction prefix,
or a 0xf6 or 0xf7 opcode then a warning is given since DTRACE is unable to determine
the true instruction type.
7) Too many unique jump targets within a single tracepoint. The current maximum is 256.
8) Unsupported RPN commands. The RPN command set has been increased over several releases
and fix pack for OS/2. It is possible that DTRACE would permit the coding of an
unsupported RPN command on an earlier release.
----------------------------------------------------------------------
Trace Program Examples:
The following examples illustrate common usages of the RPN commands.
1) Log AX and BX registers:
Push EBX
Push EAX
Log WN,2 ;lower 16 bits of each DWORD
2) Log EIP, EBP and EAX:
Push EAX
Push EBP
Push EIP
Log DN,3 ;3 DWORDs from the stack
3) Log value at EBP+ESI:
Push W,4 ; push immediate value 4 - length to log
Push EBP
Push ESI
Add ; add top two DWORDs - puts EBP+ESI on stack
Log MRF ; log memory at flat address range
4) Log value at SS:SP using 16-bit segmented addressing:
Push W,9 ; push immediate value 9 - length to log
Push SS
Push ESP
Log MRS ; log memory at segmented address range
5) Log 16 bytes of data pointed to by the flat address at SS:SP+8
Push W,16 ; push immediate value 16 - length to log
Push SS
Push ESP
Push 8 ; offset 8
Add ; 8 added to ESP value on stack
Push SIS ; pop ESP then SS and pop Dword at that address
; as two Words extended to Dwords (as if it was a sel:offset).
; stack now contains the length and split address of data to log
Cnvrt SXD ; Concatenate the two words to form a flat address
Log MRF ; log the data.
6) This example shows an RPN fragment that extracts and logs the
Tid and Slot number of the thread making the trace entry.
The current TCB is located via the SAS and the Tid/Slot are taken
from the 1st word of the TCB. This example requires 2 local
variables defining for temporary use.
; get the slot and tid from the SAS
; requires 2 variables to be defined for temporary use.
push w,0x70;SAS selector (used later)
push w,0x70;SAS selector
push w,0x0e;offset to tasking section offset
push wis
move v,0 ;save tasking section offset
push w,0xa ;offset to slot no address
add ;TOS=sel:off-> @tasknumber
push sis ;(using first push w,0x70)
cnvrt sxd ;TOS->tasknumber
push fif ;fetch slot number
push w,4 ;scale by 4
mul ;convert to index into tcb ptrs table
move v,1 ;save offset into TCB table
pop n,1
push w,0x70
push v,0 ;offset into tasking section
push w,0x6 ;offset to @TCB ptrs addr
add
push sis
cnvrt sxd ;address of @tcb table on stack
push fif ;addres of tcb table on TOS
push v,1 ;offset into table for current thread
add
push fif ;current tcb address on stack
push fif ;slot/tid on TOS
log dn,1 ;w2=slot w1=tid
----------------------------------------------------------------------
Complete Examples:
In the following examples, object, offset and opcode must be altered
accordingly before running any of these on an OS/2 system.
1) Trace DOSREAD and DOSWRIT. Dump the SS:ESP and 0x20 bytes of the stack.
Define 1 Dynamic Trace variable and increment it each time the tracepoint
fires.
major=0xfc
vars=1
id=2
;
;DOSREAD
;
minor=1
opcode=0x55; push
object=0x3
offset=0x4008
push ss
push esp
log wn,2
push W,0x20
push ss
push esp
log mrs
inc v,0
;
;DOSWRITE
;
minor=2
opcode=0xc8 ;enter
object=0x5
offset=0x9a4
push ss
push esp
log wn,2
push W,0x20
push ss
push esp
log mrs
;
2) Monitor the number of calls to WinSendMsg and WinPostMsg.
major=0xfb
vars=2
id=1
;
;WinSendMsg
;
minor=1
opcode=0x58 ;push
object=0x1
offset=0x2730
inc v,0
abort
;
;WinPostMsg
;
minor=2
opcode=0x36
object=1
offset=0xde73
inc v,1
abort
3) Trace 4 entry points to HPFS.IFS. Log the stack pointer and 20 bytes of
data.
major=0xfd
;
;FS_READ - HPFS
;
minor=1
opcode=0xc8 ;enter
object=0x1
offset=0x11ac
push ss
push esp
log wn,2
push W,0x20
push ss
push esp
log mrs
;
;FS_WRITE - HPFS
;
minor=2
opcode=0xc8 ;enter
object=0x1
offset=0x114c
push ss
push esp
log wn,2
push W,0x20
push ss
push esp
log mrs
;FS_CHDIR - HPFS
;
minor=3
opcode=0xc8 ;enter
object=0x2
offset=0x1fc
push ss
push esp
log wn,2
push W,0x20
push ss
push esp
log mrs
;FS_CLOSE - HPFS
;
minor=4
opcode=0xc8 ;enter
object=0x1
offset=0x5cc
push ss
push esp
log wn,2
push W,0x20
push ss
push esp
log mrs
;FS_OPENCREATE - HPFS
;
minor=5
opcode=0xc8 ;enter
object=0x2
offset=0x2168
push ss
push esp
log wn,2
push W,0x20
push ss
push esp
log mrs
4) Trace all the entry points to HPFS386 with custom formatting.
The HPFS386.RPN file is as follows:
;
major=0xfa
;
;
; Trace HPFS386 FSD entry points
;
;
;0005:001C HPFS386:CODE16:FS_ALLOCATEPAGESPACE
minor=0x100
object=5
offset=0x1c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;
;0005:002C HPFS386:CODE16:FS_CANCELLOCKREQUEST
minor=0x101
object=5
offset=0x2c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:003C HPFS386:CODE16:FS_CHDIR
minor=0x102
object=5
offset=0x3c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:004C HPFS386:CODE16:FS_CHGFILEPTR
minor=0x103
object=5
offset=0x4c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:005C HPFS386:CODE16:FS_CLOSE
minor=0x104
object=5
offset=0x5c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:006C HPFS386:CODE16:FS_COMMIT
minor=0x105
object=5
offset=0x6c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:007C HPFS386:CODE16:FS_DELETE
minor=0x106
object=5
offset=0x7c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:008C HPFS386:CODE16:FS_DOPAGEIO
minor=0x107
object=5
offset=0x8c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:009C HPFS386:CODE16:FS_EXIT
minor=0x108
object=5
offset=0x9c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:00AC HPFS386:CODE16:FS_FILEATTRIBUTE
minor=0x109
object=5
offset=0xac
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:00BC HPFS386:CODE16:FS_FILEINFO
minor=0x10a
object=5
offset=0xbc
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:00CC HPFS386:CODE16:FS_FILEIO
minor=0x10b
object=5
offset=0xcc
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:00DC HPFS386:CODE16:FS_FILELOCKS
minor=0x10c
object=5
offset=0xdc
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:00EC HPFS386:CODE16:FS_FINDCLOSE
minor=0x10d
object=5
offset=0xec
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:00FC HPFS386:CODE16:FS_FINDFIRST
minor=0x10e
object=5
offset=0xfc
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:010C HPFS386:CODE16:FS_FINDFROMNAME
minor=0x10f
object=5
offset=0x10c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:011C HPFS386:CODE16:FS_FINDNEXT
minor=0x110
object=5
offset=0x11c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:012C HPFS386:CODE16:FS_FINDNOTIFYCLOSE
minor=0x111
object=5
offset=0x12c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:013C HPFS386:CODE16:FS_FINDNOTIFYFIRST
minor=0x112
object=5
offset=0x13c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:014C HPFS386:CODE16:FS_FINDNOTIFYNEXT
minor=0x113
object=5
offset=0x14c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:015C HPFS386:CODE16:FS_FLUSHBUF
minor=0x114
object=5
offset=0x15c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:016C HPFS386:CODE16:FS_FSCTL
minor=0x115
object=5
offset=0x16c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:017C HPFS386:CODE16:FS_FSINFO
minor=0x116
object=5
offset=0x17c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:018C HPFS386:CODE16:FS_IOCTL
minor=0x117
object=5
offset=0x18c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:019C HPFS386:CODE16:FS_MKDIR
minor=0x118
object=5
offset=0x19c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:01AC HPFS386:CODE16:FS_MOUNT
minor=0x119
object=5
offset=0x1ac
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:01BC HPFS386:CODE16:FS_MOVE
minor=0x11a
object=5
offset=0x1bc
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:01CC HPFS386:CODE16:FS_NEWSIZE
minor=0x11b
object=5
offset=0x1cc
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:01DC HPFS386:CODE16:FS_OPENCREATE
minor=0x11c
object=5
offset=0x1dc
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:01EC HPFS386:CODE16:FS_OPENPAGEFILE
minor=0x11d
object=5
offset=0x1ec
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:01FC HPFS386:CODE16:FS_PATHINFO
minor=0x11e
object=5
offset=0x1fc
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:020C HPFS386:CODE16:FS_READ
minor=0x11f
object=5
offset=0x20c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:021C HPFS386:CODE16:FS_RMDIR
minor=0x120
object=5
offset=0x21c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:022C HPFS386:CODE16:FS_SHUTDOWN
minor=0x121
object=5
offset=0x22c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;0005:023C HPFS386:CODE16:FS_WRITE
minor=0x122
object=5
offset=0x23c
opcode=0xb8 ;move
push ss
push esp
log wn,2
push w,0x20
push ss
push esp
log mrs
;
;
;
The TSF file for TRCUST is as follows:
MODNAME = HPFS386
MAJOR = 250
MAXDATALENGTH = 512
TRACE MINOR = 0x100
TP = @STATIC
DESC = "HPFS386 FS_ALLOCATEPAGESPACE"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x101
TP = @STATIC
DESC = "HPFS386 FS_CANCELLOCKREQUEST"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x102
TP = @STATIC
DESC = "HPFS386 FS_CHDIR"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x103
TP = @STATIC
DESC = "HPFS386 FS_CHGFILEPTR"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x104
TP = @STATIC
DESC = "HPFS386 FS_CLOSE"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x105
TP = @STATIC
DESC = "HPFS386 FS_COMMIT"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x106
TP = @STATIC
DESC = "HPFS386 FS_DELETE"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x107
TP = @STATIC
DESC = "HPFS386 FS_DOPAGEIO"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x108
TP = @STATIC
DESC = "HPFS386 FS_EXIT"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x109
TP = @STATIC
DESC = "HPFS386 FS_FILEATTRIBUTE"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x10a
TP = @STATIC
DESC = "HPFS386 FS_FILEINFO"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x10b
TP = @STATIC
DESC = "HPFS386 FS_FILEIO"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x10c
TP = @STATIC
DESC = "HPFS386 FS_FILELOCKS"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x10d
TP = @STATIC
DESC = "HPFS386 FS_FINDCLOSE"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x10e
TP = @STATIC
DESC = "HPFS386 FS_FINDFIRST"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x10f
TP = @STATIC
DESC = "HPFS386 FS_FINDFROMNAME"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x110
TP = @STATIC
DESC = "HPFS386 FS_FINDNEXT"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x111
TP = @STATIC
DESC = "HPFS386 FS_FINDNOTIFYCLOSE"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x112
TP = @STATIC
DESC = "HPFS386 FS_FINDNOTIFYFIRST"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x113
TP = @STATIC
DESC = "HPFS386 FS_FINDNOTIFYNEXT"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x114
TP = @STATIC
DESC = "HPFS386 FS_FLUSHBUF"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x115
TP = @STATIC
DESC = "HPFS386 FS_FSCTL"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x116
TP = @STATIC
DESC = "HPFS386 FS_FSINFO"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x117
TP = @STATIC
DESC = "HPFS386 FS_IOCTL"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x118
TP = @STATIC
DESC = "HPFS386 FS_MKDIR"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x119
TP = @STATIC
DESC = "HPFS386 FS_MOUNT"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x11a
TP = @STATIC
DESC = "HPFS386 FS_MOVE"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x11b
TP = @STATIC
DESC = "HPFS386 FS_NEWSIZE"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x11c
TP = @STATIC
DESC = "HPFS386 FS_OPENCREATE"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x11d
TP = @STATIC
DESC = "HPFS386 FS_OPENPAGEFILE"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x11e
TP = @STATIC
DESC = "HPFS386 FS_PATHINFO"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x11f
TP = @STATIC
DESC = "HPFS386 FS_READ"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x120
TP = @STATIC
DESC = "HPFS386 FS_RMDIR"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x121
TP = @STATIC
DESC = "HPFS386 FS_SHUTDOWN"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
TRACE MINOR = 0x122
TP = @STATIC
DESC = "HPFS386 FS_WRITE"
FMT = "SS:ESP=%A"
FMT = "Stack %R%W"
The formatting file is generated using TRCUST and the resulting
TRC00FA.TFF is copied to OS2\SYSTEM\TRACE
The commands executed to record the trace and spool the data to
a disk files are (where hmte has been first obtained from a source
such as Theseus/2 or the Kernel Debugger or the Dump Formatter):
DTRACE APPLY HPFS386.RPN /h=0x"hmte"
TRSPOOL /W
Change history:
---------------
5 Feb 96 Richard Moore 1.0 Created
10 Feb 96 Richard Moore 1.1 QUERY/GETVARS added.
20 Mar 96 Richard Moore 1.2 SysDump/And/Or/Xor/Not/Exit/
ProcDump RPN support added.
27 Mar 96 Richard Moore 1.3 Add /Q Quiet option and Fix /R.
2 Apr 96 Richard Moore 2.0 Added support for labels in the RPN
program.
3 Apr 96 Richard Moore 2.1 Minor bug fix, where ':' in comment is
not processes correctly.
Added more RPN examples.
5 May 96 Richard Moore 2.2 Allow name to be specified in the RPN
file. Allow the RPNs program to be
optional. Fix error handling and add
information messages. Document logmax.
17 Jun 96 Richard Moore 2.3 Add SetMaj/SetMajW SetMin/SetMinW Xchg
16 Aug 96 Richard Moore 2.3a Documentation update. Define DTO and
Remove reference to TRACE command in
examples.
17 Aug 96 Richard Moore 2.4 Allow name to specify a file
extension. Allow OS2KRNLx and
OS2KRNL to be aliases of DOSCALLS.DLL
Ignore any ctrl chars in rpn file.
18 Aug 96 Richard Moore 2.5 Allow Major code overrides. Clarify
error messages. Fix REMOVE file_name.
Allow DTRACE to be compatible with
TDFLST output. This introduces four
new keywords that are recognised but
ignored. These are:
GROUPDEF, TYPEDEF, GROUP, TYPE
23 Aug 96 Richard Moore 2.6 Fix PUSH CS, was erroneously
PUSH ECS.
1 Sep 96 Richard Moore 3.0 Implement the BUILDTDF function.
Benign bug fix: erroneous PUSH EAX was
being generated after each tracepoint
definition.
20 Sep 96 Richard Moore 3.1 Delay DosFreeModule until after
DosDynamicTrace. Fix doc error in example.
16 Dec 96 Richard Moore 3.1a minor editorial changes to the
documentation.
09 Jan 97 Richard Moore 3.2 Add support for non *.DLL named modules.
Clarify use if id and name parameters.
Add info on use of TRACE.EXE with non-*.DLL
modules and dynamic tracing at interrupt
time.
16 Jan 97 Richard Moore 3.3 Add support for *.EXEs, both with standard
and non-standard extensions.
21 Feb 97 Richard Moore 3.4 Improved module search for all module types.
Simple names and names with extension may
be specified for any DLL that is in LIBPATH
or current directory or other module in PATH.
GETVARS now displays hex/dec values.
Made .RPN the default extension for RPN files.
Fix PRN cmd parser error.
Added /D switch for debugging DTRACE.
Disable dosfreemodule to avoid IPEs.
25 Feb 97 Richard Moore 3.4a @0004
Improved error processing. Fixed hang when
taking an error path and DosKillProcess is
outstanding.
29 Apr 97 Richard Moore 3.5 @0005
Fixed label limit. Improved /Q. Allowed
/M /N /Q /D with BUILDTDF. Added /M to help
and documentation.
23 May 97 Richard Moore 3.6 @0006
Add error checking to numeric values. Allow
assembler style hexadecimal constants (xxxxh).
Diagnostic DTRACE.TDF and TRC0063.TFF generated.
24 May 97 Richard Moore 3.7 @0007
Fix CLEARALL /Q
07 Juk 97 Richard Moore 3.7a minor correction to debug msg
10 Sep 97 Richard Moore 3.8 @0008
Added new RPN commands for f180062
06 Oct 97 Richard Moore 4.0 @0009 F180062 additions:
1) Enhanced Query /x=[n] n=0-1
2) Fix Query and Getvars to
access non-active DTOs.
3) Add /a for Query all DTOs.
4) Add merge factity to APPLY
and REMOVE (/e).
5) REMOVE with /c @0010
6) Expanded help @0010
23 Oct 97 Richard Moore 4.1 @0010 correct info message for REMOVE /E
07 Nov 97 Richard Moore 4.2 @0011 correct DTR status info
05 Dec 97 Richard Moore 4.2 @0012 minor help corrections
06 Sep 98 Richard Moore 4.3 @0013 fix logic for handling Base Device Drivers
Add Opcode validation.
Allow whitespace and tab characters.