|
GEOS SDK TechDocs
|
|
6 Coding
|
6.2 Examples
symbol, type, patient, handle, brk, cbrk, event, thread, src, cache, table
This section contains information about Swat's built-in data structures and the commands that access them. These commands examine and modify vital information about the state of GEOS while it is running under Swat.
brk
brk <addr> [<command>]
brk pset <addr> [<command>]
brk aset <addr> [<command>]
brk tset <addr> [<command>]
brk clear <break>*
brk delete <break>*
brk enable <break>*
brk disable <break>*
brk address <break>
brk list [<addr>]
brk debug [<flag>]
brk isset <addr>
brk cond <break> <condition>*
brk cmd <break> [<command>]
brk delcmd <break> [<command>]
Examples:
- "brk WinOpen"
-
Sets the machine to stop unconditionally when any thread calls WinOpen.
- "brk pset WinOpen"
-
Sets the machine to stop when any thread for the current patient calls WinOpen.
- "brk tset WinOpen"
-
Sets the machine to stop when any thread for the current patient calls WinOpen, and deletes the breakpoint when the machine next stops.
- "brk enable 1 3-5"
-
Re-enables breakpoints 1, 3, 4, and 5
- "brk clear 2-"
-
Clears all breakpoints from number 2 onward.
- "brk cond 3 cx=42"
-
Sets breakpoint 3 to be conditional, stopping when the machine reaches the breakpoint's address with CX being 42.
- "brk cond 2 (ss:0)!=1b80h"
-
Sets breakpoint 2 to be conditional, stopping when the machine reaches the breakpoint's address with the word at ss:0 not being 1b80h. Note that the "ss" is the value of the
ss register when the "brk cond" command is executed, not when the breakpoint is reached.
Allows you to specify that execution should stop when it reaches a particular point. These breakpoints can be conditional, and can execute an arbitrary Tcl command, which can say whether the machine is to remain stopped, or continue on its way.
- Once you've set a breakpoint, "brk" will return to you a token for that breakpoint that begins with "brk" and ends with a number. When you refer to the breakpoint, you can use either the full name (as you'll usually do from a Tcl procedure), or just the number.
- Breakpoints have four attributes: the address at which they are set, the condition set on their being recognized, the Tcl command string to execute when they are recognized, and the Tcl command string to execute when they are deleted.
- The condition is set either when the breakpoint is set, using the "cbrk" command, or after you've set the breakpoint, by invoking the "brk cond" command.
- A breakpoint's condition is evaluated (very quickly) on the PC and can check only word registers (the 8 general registers, the three segment registers other than CS, and the current thread; each register may be checked only once in a condition) and a single word of memory. Each <condition> argument is of the form "<reg><op><value>". <reg> is one of the 16-bit machine registers, "thread" (for the current thread), or the address of a word of memory to check, enclosed in parentheses. <op> is a relational operator taken from the following set:
- =
- equal-to
- !=
- not-equal-to
- > < >= <=
- unsigned greater-than, less-than, greater-or-equal, and
less-or-equal
- +> +< +>= +<=
- signed greater-than, less-than, greater-or-equal, and
less-or-equal
<value> is a regular Swat address expression. If it is handle-relative, and the <reg> is one of the three non-CS segment registers, the condition will be for the segment of that handle and will change automatically as the handle's memory shifts about on the heap. Similar things will happen if you specify a number as the <value> for a segment register and the number is the current segment of a block on the heap.
- If you give no <condition> argument to the "brk cond" command, you will remove any condition the breakpoint might have, making it, therefore, unconditional.
- If a breakpoint is given an associated <command> string, it will be evaluated before the breakpoint is taken. If the result of the evaluation is an error, a non-numeric string, or a numeric string that's non-zero, the breakpoint will be taken. Otherwise, the machine will be allowed to continue (so long as no other breakpoint command or other part of Swat insists that it remain stopped). You can use this to simply print out information when execution reaches the breakpoint address without interrupting the machine's execution.
- The global variable "breakpoint" contains the name of the breakpoint whose command is being evaluated while that command is being evaluated.
- You can change the command associated with a breakpoint with the "brk cmd" command. If you give no <command> argument, then no command will be executed and the breakpoint will always be taken, so long as any associated condition is also met.
- If a breakpoint has both a condition and a command, the command will not be executed until the condition has been met, unless there's another breakpoint at the same address with a different, or no, condition.
- You can set a breakpoint to last only during the next continuation of the machine by calling "brk tset". The breakpoint thus set will be removed when next the machine comes to a full stop, regardless of why it stopped (i.e. if it hits a different breakpoint, the temporary breakpoint will still be removed). The breakpoint will only be taken if the thread executing when it is hit is owned by the patient that was current when the breakpoint was set.
- Each <break> argument to the "brk clear", "brk enable" and "brk disable" commands can be either a single breakpoint token (or number), or a range of the form <start>-<end>, where either <start> or <end> may be absent. If <start> is missing, the command affects all breakpoints from number 1 to <end>. If <end> is missing, the command affects all breakpoints from <start> to the last one in existence.
- If you give no <break> argument to "brk clear", "brk enable" or "brk disable", the command will apply to all breakpoints that are specific to the current patient, i.e. that were set with the "brk pset" command, unless the current patient is the kernel, in which case they will apply to all breakpoints that are specific to no patient (i.e. those set with the "brk aset" or "brk <addr>" commands).
- "brk address" returns the address expression for where the breakpoint is set. This will usually be of the form ^h<handle-id>:<offset>, with both <handle-id> and <offset> in hex (followed by an "h", of course). If the breakpoint is set at an absolute address, you will get back only a single hex number, being the linear address at which the breakpoint is set.
- If you type "brk list" with no argument, Swat will print out a listing of the currently-active breakpoints. If you give an <addr> (address expression) argument, however, you'll be returned a list of the breakpoints set at the given address. If there are no breakpoints there, the list will be empty.
- As a shortcut, you can invoke "brk isset" to see if any breakpoints are set at the given address, if you're not interested in which ones they are.
cache
cache create (lru|fifo) <maxSize> [<flushProc>]
cache destroy <cache> [flush|noflush]
cache lookup <cache> <key>
cache enter <cache> <key>
cache invalone <cache> <entry>
cache invalall <cache> [flush|noflush]
cache key <cache> <entry>
cache size <cache>
cache maxsize <cache>
cache setmaxsize <cache> <maxSize>
cache getval <cache> <entry>
cache setval <cache> <entry> <value>
Examples:
-
"var cache [cache create lru 10]"
-
Creates a cache of 10 items that are flushed on a least-recently-used basis. The returned token is saved for later use.
-
"var entry [cache lookup $cache mom]"
-
Sees if an entry with the key "mom" is in the cache and saves its entry token if so.
-
"echo mom=[cache getval $cache $entry]"
-
Retrieves the value stored in the entry for "mom" and echoes it.
-
"cache invalone $cache $entry"
-
Flushes the entry just found from the cache.
-
"cache destroy $cache"
-
Destroys the cache.
The cache command, as the name implies, maintains a cache of data that is keyed by strings. When a new entry is added to an already-full cache, an existing entry is automatically flushed based on the usage message with which the cache was created:
lru
(last recently used) or
fifo
(first in, first out). If
lru
, the least-recently-used entry is flushed; if
fifo
, the oldest entry is flushed.
-
Unlike the "table" command, the "cache" command returns tokens for entries, not their values. This allows entries to be individually flushed or their values altered.
-
If a <flushProc> is specified when the cache is created, the procedure will be called each time an entry is flushed from the cache. It will be called "<flushProc> <cache> <entry>" where <cache> is the token for the cache, and <entry> is the token for the entry being flushed.
-
If the maximum size of a full cache is reduced, entries will be flushed from the cache to bring it down to the new maximum size. The <flushProc> will be called for each of them.
-
If the values stored in the cache entries should not be freed when the cache is destroyed, pass "noflush" to "cache destroy". The default is to flush (and hence call the <flushProc>) all entries from the cache before it is destroyed.
-
If the values stored in the cache entries should not be freed when the cache is flushed, pass "noflush" to "cache invalall". The default is to call the <flushProc> for each entry in the cache before it is actually flushed.
-
If an entry is not found in the cache, "cache lookup" will return an empty string.
-
When an entry is created, "cache enter" returns a 2-list containing the entry token as its first element, and an integer, as its second element, that is either non-zero or 0, to tell if the entry is new or was already present, respectively.
cbrk
cbrk <addr> <condition>*
cbrk aset <addr> <condition>*
cbrk tset <addr> <condition>*
cbrk clear <break>*
cbrk delete <break>*
cbrk enable <break>*
cbrk disable <break>*
cbrk address <break>
cbrk list [<addr>]
cbrk debug [<flag>]
cbrk isset <addr>
cbrk cond <break> <condition>*
cbrk cmd <break> [<command>]
cbrk delcmd <break> [<command>]
Examples:
-
"cbrk WinOpen di=1b80h"
-
Stops the machine when execution reaches WinOpen() with
di
set to 1b80h.
Allows you to set fast conditional breakpoints.
-
All these subcommands function the same as for the "brk" command, with the exception of the "aset" and "tset" commands, which expect the condition for the breakpoint, rather than an associated command.
-
There are a limited number of these sorts of breakpoints that can be set in the PC (currently 8), so they should be used mostly for heavily-travelled areas of code (e.g. inner loops, or functions like
ObjCallMethodTable()
in the kernel).
-
For more information on the subcommands and the format of arguments, see the documentation for the "brk" command.
event
event <subcommand>
The
event
command provides access to Swat's internal events. The subcommands are as follows:
-
handle <eventName> <handler> [<data>]
-
The <handler> procedure is invoked each time an event of type <eventName> is dispatched. The handler receives two arguments: an event-specific piece of data, and the given <data>. A handler procedure should be declared
proc <handler> {arg data} {<body>}
The
handle
subcommand returns an <event> for later use in deleting it. The <handler> should return one of
event_handled
,
event_not_handled
, or
event_stop_handling
. If it returns
event_stop_handling
, the event will not be dispatched to any other handlers of the event.
-
delete <event>
-
Deletes the given event handler given by the
event handle
command.
-
dispatch <eventName> <arg> -
Dispatches the given event with the given <arg> to all handlers of that event. If <eventName> is a pre-defined event type, <arg> will be converted to the appropriate type before being dispatched. Otherwise it is passed as a string.
-
create
- Returns a number that represents a new event type. Handlers may then be defined for and events dispatched of the new type.
-
list
- Lists all Tcl-registered events by event-name and handler function.
The events which are currently defined are:
-
FULLSTOP
-
Generated when patient stops for a while. Argument is string telling why the patient stopped.
-
CONTINUE
-
Generated just before the patient is continued. The argument is non-zero if going to single-step.
-
TRACE
- Generated when the execution of a source line completes and the patient is in line-trace mode.
-
START
- Generated when a new patient/thread is created. Argument is patient token of the patient involved.
-
STACK
- Current stack frame has changed. The argument is non-zero if the stack change comes from a change in patients/threads or zero if the change comes from actually going up or down the stack in the current patient.
-
DETACH
- Detaching from the PC. The argument is always zero.
-
RESET
- Returning to the top level. The argument is always zero.
-
ATTACH
- Attached to the PC. The argument is always zero.
-
RELOAD
- Kernel was reloaded. The argument is always zero.
-
CHANGE
- Current patient has changed. The argument is the token for the previous patient.
-
STEP
-
Machine has stepped a single instruction. The argument is the value to pass to
patient stop
if you wish the machine to stay stopped.
-
STOP
- Machine has hit a breakpoint. The argument is the value to pass to
patient stop
if you wish the machine to stay stopped.
-
INT
- Machine has hit some other interrupt that's being caught. The argument is the interrupt number. The machine will remain stopped unless it is continued with continue-patient.
handle
handle lookup <id>
handle find <address>
handle all
handle nointerest <interest-record>
handle interest <handle> <proc> [<data>+]
handle segment <handle>
handle size <handle>
handle state <handle>
handle owner <handle>
handle patient <handle>
handle other <handle>
handle id <handle>
handle isthread <handle>
handle iskernel <handle>
handle isfile <handle>
handle isvm <handle>
handle ismem <handle>
Examples:
-
"handle lookup [read-reg bx]"
-
get the handle token for the handle whose ID is in the BX register.
-
"handle interest $h ob-interest-proc [concat si=$chunk $message]"
-
call ob-interest-proc, passing the list {si=$chunk $message}, whenever the state of the handle whose token is in $h changes.
-
"handle patient $h"
-
get the token for the patient that owns the handle whose token is in $h
-
"handle all"
-
get the list of the ID's of all handles currently in Swat's handle table.
The "handle" command provides access to the structures Swat uses to track memory and thread allocation on the PC.
-
As with most other commands that deal with Swat structures, you use this one by calling a lookup function (the "lookup" and "find" subcommands) to obtain a token that you use for further manipulations. A handle token is also returned by a few other commands, such as addr-parse.
-
Handle tokens are valid only until the machine is continued. If you need to keep the token for a while, you will need to register interest in the handle using the "interest" subcommand. Most handles tokens will simply be cached while the machine is stopped and flushed from the cache when the machine continues. Only those handles for which all state changes must be known remain in Swat's handle table. For example, when a conditional breakpoint has been registered with the stub using the segment of a handle, the condition for that breakpoint must be updated immediately should the memory referred to by the handle be moved, swapped or discarded. Keeping the number of tracked handles low reduces the number of calls the stub must make to tell Swat about handle-state changes.
-
The <id> passed to the "lookup" subcommand is an integer. Its default radix is decimal, but you can specify the radix to use in all the usual ways. The value returned is the token to use to obtain further information about the handle.
-
"handle size" returns the number of bytes allocated to the handle.
-
"handle segment" returns the handle's segment (if it's resident) in decimal, as it's intended for use by Tcl programs, not people.
-
"handle owner" returns the token of the handle that owns the given handle, not its ID.
-
"handle all" returns a list of handle ID numbers not a list of handle tokens. The list is only those handles currently known to Swat.
-
"handle interest" tells Swat you wish to be informed when the handle you pass changes state in some way. The procedure <proc> will be called with two or more arguments. The first is the token of the handle whose state has changed, and the second is the state change the handle has undergone, taken from the following set of strings:
-
swapin
- Block swapped in from disk/memory
-
load
- Resource freshly loaded from disk
-
swapout
- Block swapped to disk/memory
-
discard
- Block discarded
-
resize
- Block changed size and maybe moved
-
move
- Block moved on heap
-
free
- Block has been freed
-
fchange
- Block's
HeapFlags
changed
Any further arguments are taken from the <data>+ arguments provided when you expressed interest in the handle. This subcommand returns a token for an interest record that you pass to "handle nointerest" when you no longer care about the handle. When the block is freed (the state change is "free"), there is no need to call "handle nointerest" as the interest record is automatically deleted.
-
"handle state" returns an integer indicating the state of the handle. The integer is a mask of bits that mean different things:

When the integer is AND-ed with the mask for Type (0xf8000), the following values indicate the following types of handles:
-
"handle other" returns the handle's otherInfo field. Note: This isn't necessarily the otherInfo field from the PC. E.g., for resource handles, it's the symbol token of the module for the handle.
patient
patient find <name>
patient name [<patient>]
patient fullname [<patient>]
patient data [<patient>]
patient threads [<patient>]
patient resources [<patient>]
patient libs [<patient>]
patient path [<patient>]
patient all
patient stop [<addr>]
Examples:
-
"patient find geos"
-
Returns the patient token for the kernel, if it's been loaded yet.
-
"patient fullname $p"
-
Returns the permanent name for the patient whose token is stored in the variable p.
-
"patient stop $data"
-
Tells the dispatcher of the STEP event that it should keep the machine stopped when the STEP event has been handled by everyone.
This command provides access to the various pieces of information that are maintained for each patient (geode) loaded by GEOS.
-
Subcommands may be abbreviated uniquely.
-
Swat always has the notion of a "current patient", whose name is displayed in the prompt. It is this patient that is used if you do not provide a token to one of the subcommands that accepts a patient token.
-
"patient name" returns the name of a patient. The name is the non- extension portion of the geode's permanent name. It will have a number added to it if more than one instance of the geode is active on the PC. Thus, if two GeoWrites are active, there will be two patients in Swat: "write" and "write2".
-
"patient fullname" returns the full permanent name of the patient. It is padded with spaces to make up a full 12-character string. This doesn't mean you can obtain the non-extension part by extracting the 0th element of the result with the "index" command, however; you'll have to use the "range" command to get the first 8 characters, then use "index" to trim the trailing spaces off, if you want to.
-
"patient data" returns a three-element list: {<name> <fullname> <thread-number>} <name> and <fullname> are the same as returned by the "name" and "fullname" subcommands. <thread-number> is the number of the current thread for the patient. Each patient has a single thread that is the one the user looked at most recently, and that is its current thread. The current thread of the current patient is, of course, the current thread for the whole debugger.
-
"patient threads" returns a list of tokens, one for each of the patient's threads, whose elements can be passed to the "thread" command to obtain more information about the patient's threads (such as their numbers, handle IDs, and the contents of their registers).
-
"patient resources" returns a list of tokens, one for each of the patient's resources, whose elements can be passed to the "handle" command to obtain more information about the patient's resources (for example, their names and handle IDs).
-
"patient libs" returns a list of patient tokens, one for each of the patient's imported libraries. The kernel has all the loaded device drivers as its "imported" libraries.
-
"patient path" returns the absolute path of the patient's executable.
-
"patient all" returns a list of the tokens of all the patients known to Swat.
-
"patient stop" is used only in STEP, STOP and START event handlers to indicate you want the machine to remain stopped once the event has been dispatched to all interested parties. <addr> is the argument passed in the STEP and STOP events. A START event handler should pass nothing.
-
A number of other commands provide patient tokens. "patient find" isn't the only way to get one.
src
src line <addr>
src read <file> <line>
src cache [<max>]
src addr <file> <line> [<patient>]
Examples:
-
"src line cs:ip"
-
Returns a two-list holding the source-line number, and the absolute path of the file in which it lies (not in this order), that encompasses CS:IP.
-
"src read /pcgeos/appl/sdk_c/hello/hello.goc 64"
-
Reads the single given source line from the given file.
-
"src addr icdecode.c 279"
-
Returns an address-list for the start of the code produced for the given line.
-
"src cache 10"
-
Allow 10 source files to be open at a time. This is the default.
The "src" command allows the Tcl programmer to manipulate the source- line maps contained in all the geodes' symbol files.
-
The "src line" commands returns its list as {<file> <line>}, with the <file> being absolute. If no source line can be found, the empty list is returned.
-
The <file> given to the "src read" command must be absolute, as the procedure using this command may well be wrong as to Swat's current directory. Typically this name will come from the return value of a "src line" command, so you needn't worry.
-
The line returned by "src read" contains no tabs and does not include the line terminator for the line (the <lf> for UNIX, or the <cr><lf> pair for MS-DOS).
-
"src addr" returns an address-list, as returned from "addr-parse", not an address expression, as you would
pass
to "addr-parse". If the <file> and <line> cannot be mapped to an address, the result will be the empty list.
-
The <file> given to "src addr" must be the name that was given to the assembler/compiler. This includes any leading path if the file wasn't in the current directory when the assembler/compiler was run.
-
"src cache" returns the current (or new) number of open files that are cached.
symbol
symbol find <class> <name> [<scope>]
symbol faddr <class> <addr>
symbol match <class> <pattern>
symbol scope <symbol>
symbol name <symbol>
symbol fullname <symbol>
symbol class <symbol>
symbol type <symbol>
symbol get <symbol>
symbol patient <symbol>
symbol tget <symbol>
symbol addr <symbol>
symbol foreach <scope> <class> <callback> [<data>]
Examples:
-
"symbol find type LMemType"
-
Locate a type definition named LMemType
-
"symbol faddr proc cs:ip"
-
Locate the procedure in which CS:IP lies.
-
"symbol faddr {proc label} cs:ip"
-
Locate the procedure or label just before cs:ip.
-
"symbol fullname $sym"
-
Fetch the full name of the symbol whose token is in the $sym variable.
-
"symbol scope $sym"
-
Fetch the token of the scope containing the passed symbol. This will give the structure containing a structure field, or the procedure containing a local variable, for example.
Provides information on the symbols for all currently-loaded patients. Like many of Swat's commands, this operates by using a lookup function (the "find", "faddr", "match", or "foreach" subcommands) to obtain a token for a piece of data that's internal to Swat. Given this token, you then use the other subcommands (such as "name" or "get") to obtain information about the symbol you looked up.
-
There are many types of symbols that have been grouped into classes that may be manipulated with this command. For a list of the symbol types and their meaning, type "help symbol-types". The type of a symbol can be obtained with the "symbol type" command.
-
The symbol classes are as follows:
-
type
- describes any structured type: typedef, struct, record, etype, union. Symbols of this class may also be used in place of type tokens (see the "type" command).
-
field
- describes a field in a structured type: field, bitfield.
-
enum
- describes a member of an enumerated type: enum, message.
-
const
- a constant defined with EQU:
const
.
-
var
- describes any variable symbol: var, chunk, locvar, class, masterclass, variantclass.
-
locvar
- describes any local variable symbol: locvar, locstatic.
-
scope
- describes any symbol that holds other symbols within it: module, proc, blockstart, struct, union, record, etype.
-
proc
- describes only proc symbols.
-
label
- describes any code-related symbol: label, proc, loclabel.
-
onstack
- describes only symbols created by the directive.
-
module
- describes only segment/group symbols.
-
profile
- describes a symbol that marks where profiling code was inserted by a compiler or assembler.
-
The <class> argument for the "find", "faddr" and "match" subcommands may be a single class, or a space-separated list of classes. For example, "symbol faddr {proc label} CS:IP" would find the symbol closest to CS:IP (but whose address is still below or equal to CS:IP) that is either a procedure or a label.
-
The "symbol find" command locates a symbol given its name (which may be a symbol path).
-
The "symbol faddr" command locates a symbol that is closest to the passed address.
-
A symbol's "fullname" is the symbol path, from the current patient, that uniquely identifies the symbol. Thus if a procedure-local variable belongs to the current patient, the fullname would be
<segment>::<procedure>::<name>
where <segment> is the segment holding the <procedure>, which is the procedure for which the local variable named <name> is defined.
-
You can force the prepending of the owning patient to the fullname by passing <with-patient> as a non-empty argument ("yes" or "1" are both fine arguments, as is "with-patient").
-
The "symbol get" commands provides different data for each symbol class, as follows:
-
var, locvar, chunk: {<addr> <sclass> <type>}
-
<addr> is the symbol's address as for the "addr" subcommand, <sclass> is the storage class of the variable and is one of static (a statically allocated variable), lmem (an lmem chunk), local (a local variable below the frame pointer), param (a local variable above the frame pointer), or reg (a register variable; address is the machine register number -- and index into the list returned by the "current-registers" command).
-
object class: {<addr> <sclass> <type> <flag> <super>}
-
first three elements same as for other variables. <flag> is "variant" if the class is a variant class, "master" if the class is a master class, or empty if the class is nothing special. <super> is the symbol token of the class's superclass.
-
label-class: {<addr> (near|far)}
-
<addr> is the symbol's address as for the "addr" subcommand. The second element is "near" or "far" depending on the type of label involved.
-
field-class: {<bit-offset> <bit-width> <field-type> <struct-type>}
-
<bit-offset> is the offset of the field from the structure/union/record's base expressed in bits. <bit-width> is the width of the field, in bits. <field-type> is the type for the field itself, while <struct-type> is the token for the containing structured type.
-
const: {<value>}
-
<value> is just the symbol's value.
-
enum-class: {<value> <etype>}
-
<value> is the symbol's value. <etype> is the enumerated type's symbol.
-
blockstart, blockend: {<addr>}
-
<addr> is the address bound to the symbol.
-
onstack: {<addr> <data>}
-
<addr> is the address at which the ON_STACK was declared. <data> is the arguments given to the ON_STACK directive.
-
module: {<patient>}
-
<patient> is the token for the patient owning the module.
-
A related command, "symbol tget" will fetch the type token for symbols that have data types (var-, field- and enum-class symbols).
-
"symbol addr" can be used to obtain the address of symbols that actually have one (var-, locvar- and label-class symbols). For locvar symbols, the address is an offset from the frame pointer (positive or negative). For var- and label-class symbols (remember that a procedure is a label-class symbols), the returned integer is the offset of the symbol within its segment.
-
"symbol patient" returns the token of the patient to which the symbol belongs.
-
"symbol foreach" will call the <callback> procedure for each symbol in <scope> (a symbol token) that is in one of the classes given in the list <class>. The first argument will be the symbol token itself, while the second argument will be <data>, if given. If <data> wasn't provided, <callback> will receive only 1 argument. <callback> should return 0 to continue iterating, or non-zero to stop. A non-integer return is assumed to mean stop. "symbol foreach" returns whatever the last call to <callback> returned.
-
By default, "symbol scope" will return the physical scope of the symbol. The physical scope of a symbol is the symbol for the segment in which the symbol lies, in contrast to the lexical scope of a symbol, which is where the name of the symbol lies. The two scopes correspond for all symbols but static variables local to a procedure. To obtain the lexical scope of a symbol, pass <lexical> as a non-zero number.
See Also: type.
table
table create [<initBuckets>]
table destroy <table>
table enter <table> <key> <value>
table lookup <table> <key>
table remove <table> <key>
Examples:
-
"var kitchen [table create 32]"
-
Create a new table with 32 hash buckets initially.
-
"table enter $t tbrk3 {1 2 3}"
-
Enter the value "1 2 3" under the key "tbrk3" in the table whose token is stored in the variable t.
-
"table lookup $t tbrk4"
-
Fetch the value, if any, stored under the key "tbrk4" in the table whose token is stored in the variable t.
-
"table remove $t tbrk3"
-
Remove the data stored in the table, whose token is stored in the variable t, under the key "tbrk3"
-
"table destroy $t"
-
Destroy the table $t and all the data stored in it.
(mess1:0) 159 => var yearTable [table create]
(mess1:0) 160 => table enter $yearTable synclavier 1979
(mess1:0) 161 => table enter $yearTable moog 1966
(mess1:0) 162 => table lookup $yearTable synclavier
1979
(mess1:0) 163 => var yearTable
1403188
(mess1:0) 164 => table lookup 1403188 moog
1966
(mess1:0) 165 => table remove $yearTable synclavier
(mess1:0) 166 => table lookup $yearTable synclavier
nil
(mess1:0) 167 => table destroy $yearTable
The "table" command is used to create, manipulate and destroy hash tables. The entries in the table are keyed on strings and contain strings, as you'd expect from Tcl.
-
The <
initBuckets
> parameter to "table create" is set based on the number of keys you expect the table to have at any given time. The number of buckets will automatically increase to maintain hashing efficiency, should the need arise, so <
initBuckets
> isn't a number that need be carefully chosen. It's best to start with the default (16) or perhaps a slightly larger number.
-
If no data are stored in the table under <
key
>, "table lookup" will return the string "nil", for which you can test with the "null" command.
thread
thread id <thread>
thread register <thread> <regName>
thread handle <thread>
thread endstack <thread>
thread number <thread>
thread all
Examples:
-
"thread register $t cx"
-
Fetches the value for the CX register for the given thread.
-
"thread number $t"
-
Fetches number swat assigned to thread when it was first encountered.
(mess1:0) 145 => patient threads
2667104
(mess1:0) 146 => thread id 2667104
11184
(mess1:0) 147 => thread all
767532 756068 1348520 1348868 1349216 1349748 1350236 1402096 1079392 2667104
(mess1:0) 148 => thread handle 756068
880428
(mess1:0) 149 => thread number 756068
0
Returns information about a thread, given its thread token. Thread tokens can be obtained via the "patient threads" command, or the "handle other" command applied to a thread handle's token.
-
Subcommands may be abbreviated uniquely.
-
"thread id" returns the handle ID, in decimal, of the thread's handle. This is simply a convenience.
-
"thread register" returns the contents of the given register in the thread when it was suspended. All registers except "pc" are returned as a single decimal number. "pc" is returned as two hexadecimal numbers separated by a colon, being the cs:ip for the thread. Note that GEOS doesn't actually save the AX and BX registers when it suspends a thread, at least not where Swat can consistently locate them. These registers will always hold 0xadeb unless the thread is the current thread for the machine (as opposed to the current thread for swat).
-
"thread handle" returns the token for the thread's handle.
-
"thread endstack" returns the maximum value SP can hold for the thread, when it is operating off its own stack. Swat maintains this value so it knows when to give up trying to decode the stack.
-
"thread number" returns the decimal number Swat assigned the thread when it first encountered it. The first thread for each patient is given the number 0 with successive threads being given the highest thread number known for the patient plus one.
-
"thread all" returns a list of tokens for all the threads known to Swat (for all patients).
type
type <basic-type-name>
type make array <length> <base-type>
type make pstruct (<field> <type>)+
type make struct (<field> <type> <bit-offset> <bit-length>)+
type make union (<field> <type>)+
type make <ptr-type> <base-type>
type delete <type>
type size <type>
type class <type>
type name <type> <var-name> <expand>
type aget <array-type>
type fields <struct-type>
type members <enum-type>
type pget <ptr-type>
type emap <num> <enum-type>
type signed <type>
type field <struct-type> <offset>
type bfget <bitfield-type>
Examples:
-
"type word"
- Returns a type token for a word (2-byte unsigned quantity).
-
"type make array 10 [type char]"
-
Returns a type token for a 10-character array.
-
"type make optr [symbol find type GenBase]"
-
Returns a type token for an optr (4-byte global/local handle pair) to a "GenBase" structure.
Provides access to the type descriptions by which all PC-based data are manipulated in Swat, and allows a Tcl procedure to obtain information about a type for display to the user, or for its own purposes. As with other Swat commands, this works by calling one subcommand to obtain an opaque "type token", which you then pass to other commands.
-
Type tokens and symbol tokens for type-class symbols may be freely interchanged anywhere in Swat.
-
There are 11 predefined basic types that can be given as the <basic-type-name> argument in "type <basic-type-name>". They are: byte (single-byte unsigned integer), char (single-byte character), double (eight-byte floating-point), dword (four-byte unsigned integer), float (four-byte floating-point), int (two-byte signed integer), long (four-byte signed integer), sbyte (single-byte signed integer), short (two-byte signed integer), void (nothing. useful as the base type for a pointer type), and word (two-byte unsigned integer)
-
Most type tokens are obtained, via the "symbol get" and "symbol tget" commands, from symbols that are defined for a loaded patient. These are known as "external" type descriptions. "Internal" type descriptions are created with the "type make" command and should be deleted, with "type delete" when they are no longer needed.
-
An internal structure type description can be created using either the "pstruct" (packed structure) or "struct" subcommands. Using "pstruct" is simpler, but you have no say in where each field is placed (they are placed at sequential offsets with no padding between fields), and all fields must be a multiple of 8 bits long. The "struct" subcommand is more complex, but does allow you to specify bitfields.
-
"type make pstruct" takes 1 or more pairs of arguments of the form "<field> <type>", where <field> is the name for the field and <type> is a type token giving the data type for the field. All fields must be specified for the structure in this call; fields cannot be appended to an existing type description.
-
"type make struct" takes 1 or more 4-tuples of arguments of the form "<field> <type> <bit-offset> <bit-length>". <field> is the name of the field, and <type> is its data type. <bit-offset> is the offset, in bits, from the start of the structure (starting with 0, as you'd expect). <bit-length> is the length of the field, in bits (starting with 1, as you'd expect). For a bitfield, <type> should be the field within which the bitfield is defined. For example, the C declaration:
struct {
word a:6;
word b:10;
word c;
}
would result in the command "type make struct a [type word] 0 6 b [type word] 6 10 c [type word] 16 16", because a and b are defined within a word type, and c is itself a word.
"type make union" is similar to "type make pstruct", except all fields start at offset 0. Like "pstruct", this cannot be used to hold bitfields, except by specifying a type created via "type make struct" command as the <type> for one of the fields.
"type make array <length> <base-type>" returns a token for an array of <length> elements of the given <base-type>, which may be any valid type token, including another array type.
"type make <ptr-type> <base-type>" returns a token for a pointer to the given <base-type>. There are several different classes of pointers in GEOS:
-
nptr
- a near pointer. 16-bits. points to something in the same segment as the pointer itself.
-
fptr
- a far pointer. 32-bits. segment in high word, offset in the low.
-
sptr
- a segment pointer. 16-bits. contains a segment only.
-
lptr
- an lmem pointer. 16-bits. contains a local-memory "chunk handle". data pointed to is assumed to be in the same segment as the lptr itself, but requires two indirections to get to it.
-
hptr
- a handle pointer. 16-bits. a GEOS handle.
-
optr
- an object pointer. 32-bits. contains a GEOS memory handle in the high word, and a GEOS local-memory chunk handle in the low.
-
vptr
- a VM pointer. Its 32 bits contain a GEOS file handle in the high word and a GEOS VM block handle in the low word.
-
vfptr
- a virtual far pointer. Its 32 bits contain a virtual segment in the high word and an offset in the low.
"type delete" is used to delete a type description created by "type make". You should do this whenever possible to avoid wasting memory.
Any type created by the "type make" command is subject to garbage collection unless it is registered with the garbage collector. If you need to keep a type description beyond the end of the command being executed, you must register it. See the "gc" command for details.
"type size" returns the size of the passed type, in bytes.
"type class" returns the class of a type, a string in the following set:
-
char
- for the basic "char" type only.
-
int
- any integer, signed or unsigned.
-
struct
- a structure, record, or union.
-
enum
- an enumerated type.
-
array
- an array, of course,
-
pointer
- a pointer to another type.
-
void
- nothingness. Often a base for a pointer.
-
function
- a function, used solely as a base for a pointer.
-
float
- a floating-point number.
Each type class has certain data associated with it that can only be obtained by using the proper subcommand.
"type aget" applies only to an array-class type token. It returns a four-element list: {<base-type> <low> <high> <index-type>} <base-type> is the type token describing elements of the array. <low> is the lower bound for an index into the array (currently always 0), <high> is the inclusive upper bound for an index into the array, and <index-type> is a token for the data type that indexes the array (currently always [type int]).
"type fields" applies only to a struct-class type token. It returns a list of four-tuples {<name> <offset> <length> <type>}, one for each field in the structure. <offset> is the
bit
offset from the start of the structure, while <length> is the length of the field, again in
bits
. <type> is the token for the data type of the field, and <name> is, of course, the field's name.
"type members" applies only to an enum-class type token. It returns a list of {<name> <value>} pairs for the members of the enumerated type.
"type pget" applies only to a pointer-class type token. It returns the type of pointer ("near", "far", "seg", "lmem", "handle", or "object") and the token for the type to which it points.
"type bfget" returns a three-list for the given bitfield type: {<offset> <width> <is-signed>}
"type signed" returns non-zero if the type is signed. If the <type> is not an int-class type, it is considered unsigned.
"type emap" can be used to map an integer to its corresponding enumerated constant. If no member of the enumerated type described by <type> has the value indicated, "nil" is returned, else the name of the matching constant is returned.
"type field" maps an offset into the passed struct-class type into a triple of the form {<name> <length> <ftype>}, where <name> can be either a straight field name, or a string of the form <field>.<field>... with as many .<field> clauses as necessary to get to the smallest field in the nested structure <type> that covers the given byte <offset> bytes from the start of the structure. <length> is the
bit
length of the field, and <ftype> is its type.
"type name" produces a printable description of the given type, using C syntax. <varname> is the name of the variable to which the type belongs. It will be placed at the proper point in the resulting string. If <expand> is non-zero, structured types (including enumerated types) are expanded to display their fields (or members, as the case may be).
See Also: gc,
symbol,
value.
|
GEOS SDK TechDocs
|
|
6 Coding
|
6.2 Examples