home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
-
-
-
-
- smxProbe
- Instructions for Standalone Use
-
- October 12, 1991
-
-
- When used in standalone mode (i.e. without a code debugger)
- smxProbe operates as a task called "spcon" (smxProbe control).
- In this mode, smxProbe is capable of running on a target.
-
-
- Table of Contents
-
- page
- 1. COMMANDS . . . . . . . . . . . . . . . . . . . . 2
- 1.1 Summary . . . . . . . . . . . . . . . . . . . . 2
- 1.2 Entering Commands . . . . . . . . . . . . . . . 2
-
- 2. CODE PREPARATION . . . . . . . . . . . . . . . . 3
- 2.1 Linking in smxProbe . . . . . . . . . . . . . . 3
- 2.2 Trace Buffer Sizes . . . . . . . . . . . . . . 3
- 2.3 Building the Handle Table . . . . . . . . . . . 3
- 2.4 Initialization and Exiting . . . . . . . . . . 4
- 2.5 Command Table . . . . . . . . . . . . . . . . . 4
-
- 3. THEORY OF OPERATION AND USE . . . . . . . . . . 4
- 3.1 Keyboard Entry . . . . . . . . . . . . . . . . 5
- 3.2 Screen Swap . . . . . . . . . . . . . . . . . . 5
- 3.3 Freeze Level . . . . . . . . . . . . . . . . . 6
- 3.4 Trace Buffers . . . . . . . . . . . . . . . . . 6
- 3.5 Call Triggering . . . . . . . . . . . . . . . . 7
- 3.6 Executing smx Calls Directly . . . . . . . . . 8
- 3.7 Error Trigger . . . . . . . . . . . . . . . . . 8
- 3.8 Show Control Blocks . . . . . . . . . . . . . . 9
- 3.9 Show Queues . . . . . . . . . . . . . . . . . . 9
- 3.10 Starting in Freeze Mode . . . . . . . . . . . 10
- 3.11 Target Operation . . . . . . . . . . . . . . . 10
-
- 4. TIPS . . . . . . . . . . . . . . . . . . . . . . 11
-
-
- Nomenclature
- [file name] the file in which a function or object is
- located
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1. COMMANDS
-
- 1.1 Summary
-
- name abbr ref description
- clrbk cbk 5* clear breakpoint
- freeze_at f 3.3 freeze operation at level specified
- ^f freeze on/off toggle
- setbk bk 5* set task breakpoint
- show s 3* show control block
- showb sb 3.4 show trace buffer
- showq sq 4* show queue
- showrq 4* show ready queue
- showv 3* show control block for value
- showqv 4* show queue for value
- ^s swap screens and keyboard pipes
- (hot key)
- ^r repeat last command (excluding
- control keys)
- ^t trace on/off toggle
- trigcall tr 3.5 trigger on call
- trigerr tre 3.7 trigger on error
- Esc exit trace display or spcon
-
- In the table above, the column ref refers you to the section of
- these instructions indicated, for further details. The *
- indicates sections in the other instruction booklet you have for
- smxProbe -- the one that gives specific instructions for using
- smxProbe with your code-level debugger (e.g. CodeView).
-
-
- 1.2 Entering Commands
-
- All commands except control keys and Esc are entered in C format
- with appropriate parameters, e.g.:
-
- show(timeout)
-
- Abbreviations may be used in place of full command names, e.g.:
-
- s(timeout)
-
- Do not add spaces. Press Enter to activate the command.
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
-
- 2. CODE PREPARATION
-
- 2.1 Linking in smxProbe
-
- When you desire to use smxProbe, link in the appropriate smxProbe
- library ahead of the smx library on the link command line. For
- Microsoft C, the smxProbe library must be put in the object files
- field (i.e. it is a "load library"). Two smxProbe libraries are
- provided for each memory model. The debug library (e.g.
- spsv.lib) is appropriate for use with a code debugger. The
- regular library (e.g. sps.lib) is appropriate for other versions.
- There is no test mode library. See ddemo.mak for examples. All
- modules in the smxProbe library link in. Code size is about 19K
- bytes.
-
-
- 2.2 Trace Buffer Sizes
-
- Trace buffers are automatically allocated from the far heap by
- trace_init() [trace.c] which is called from go_smx() [xgo_smx.c].
- Hence each buffer can be up to 64K bytes in size if sufficient
- memory is available. Buffer sizes are controlled by EB_SIZE,
- TTB_SIZE, and CTB_SIZE in conf.h. Maximum sizes are as follows:
-
- record size max size
- buffer size constant (bytes) (records)
- call trace CTB_SIZE 16 4096
- error EB_SIZE 10 6553
- task trace TTB_SIZE 8 8192
-
- Convenient sizes are 200, 50, and 100, respectively. Larger
- sizes will, of course, permit longer trace histories. The
- maximums above are based upon 64K bytes per buffer.
-
-
- 2.3 Building the Handle Table
-
- The handle table (ht) supplies symbolic names for smx objects and
- for a few special symbols. It is built by using BUILD_HT()
- macros after smx objects are created. For example,
-
- BUILD_HT(idle, "idle");
-
- adds an entry to ht for the idle task. See demo_init() [ddemo.c]
- for more examples. ht has an entry consisting of a handle
- pointer and a handle name per pointer. Whenever a symbolic name
- is needed, ht is searched for the handle until the first match is
- found. If no match is found, the handle is used (i.e. a 4-digit
- hex value which is the offset of its control block in DGROUP).
- Hence, it is not mandatory to use BUILD_HT for every handle.
- (It's up to you whether you want the convenience of a symbolic
- name or not.) BUILD_HT adds no code if non-test mode.
- The actual build function is build_ht(). It is invoked by
- BUILD_HT(), if in test mode. BUILD_HT() for an object should
- appear soon after creating the object and it should be invoked
-
- 3
-
-
-
-
-
-
-
- only once per object. This excludes using BUILD_HT for auto
- handles -- i.e. only static handles can be put into ht. Handle
- table initialization and builds for standard objects (e.g. idle)
- are in sp_init() in sp.c. sp_init() is called at the beginning
- of ainit() in ddcore.c, if test mode. show() and showq() cannot
- be used until after sp_init() has executed.
-
- Space for ht is allocated from the far heap by trace_init().
- Size is controlled by HT_SIZE in conf.h. HT_SIZE is calculated
- from the number of control blocks of each type. This can be
- altered, if necessary. The ht record size is 4 bytes for small
- data models and 6 bytes for large data models. This allows for
- far string pointers. However, most compilers put character
- strings in near memory unless you use an appropriate switch (/Gt=
- for Microsoft C, -Ff= for Turbo C).
-
-
- 2.4 Initialization and Exiting
-
- sp_init() should be called during initialization. (See ainit()
- in _core.c.) sp_exit() should be called when exiting the
- application. (See exitx_main() in _core.c.)
-
-
- 2.5 Command Table
-
- Most smx calls are commented out of the command table in sp.c.
- This is so that unused calls will not be linked in. These calls
- will not display symbolically in ctb nor can they be directly
- executed. To change this, merely remove "//" in front of each
- call and remake the sp library.
-
-
-
- 3. THEORY OF OPERATION AND USE
-
- The following discussion is based upon testing DOSdemo with
- smxProbe. To get up to speed as fast as possible, we suggest
- that you try the examples as you read the discussions which
- follow.
-
- Examples are inset as follows:
-
- Make one of the non-debug versions of DOSdemo, and run
- it. e.g.:
- mak l t
- run l t
- Or run the ddemolt. exe file included on the smxProbe
- disk.
-
-
-
-
-
-
-
- 4
-
-
-
-
-
-
-
- 3.1 Keyboard Entry
-
- There are two tasks which accept keyboard input:
-
- opcon operation control [ddemo.c]
- spcon smxProbe control [sp.c]
-
- Each waits at the end of a pipe (op-pipe and sp-pipe,
- respectively) for characters from the keyboard or elsewhere.
- opcon is part of DOSdemo and should also be part of your
- application.
-
- A new keyboard handler, keyin() [xkbd.c] has been created.
- keyin() replaces the BIOS keyboard handler. kbd_init() [xkbd.c],
- which is called from ainit() [ddcore.c], hooks the keyboard
- interrupt vector to keyin(). keyin() gets the scan code from the
- keyboard and converts it to an ASCII character using key_table[
- ]. (Note: this table is not complete --you can add your own
- unique codes for missing key combinations.) keyin() then puts
- the character into either op_pipe or sp_pipe, depending upon
- which is selected. op_pipe is selected initially. Thereafter,
- ^s toggles between the two pipes.
-
-
- 3.2 Screen Swap
-
- ^s is also put into the new active pipe. It causes opcon or
- spcon (whichever receives it) to swap screens. The screens are
- called "op screen" and "sp screen", respectively. Screen
- swapping is implemented by redirecting output for one screen to a
- buffer while the other screen is being output to video RAM. The
- 2000-word buffer is allocated from the far heap by sp_init()
- [sp.c]. There are actually two sets of direct screen write
- functions -- those in xcrt.c for use by operational (i.e. your)
- software, and those in spcrt.c which are reserved for use by
- smxProbe. As long as you use the xcrt.c functions none of your
- screen output will be lost while viewing sp screen.
-
- With ddemo running, hit ^s several times. You will
- notice that the counters on the op screen have
- continued to increment while looking at the sp screen.
- Note also that Esc switches from sp to op, but Esc in
- op exits.
-
- C library functions such as printf() will overwrite the sp screen
- and their output will be lost when swapping back to the op
- screen. A way around this problem is to instal a second monitor
- and monitor adapter board in your computer (you can have both VGA
- & monochrome in the same computer). Then, in sp_init() [sp.c],
- assign sp_screen to one and in crt_init() [xcrt.c] assign
- op_screen to the other. See crt_init() for how to do this. Note
- also you should remove bios_cursor_off() from ainit() [ddcore.c]
- and bios_cursor_on() from exitx_main() [ddcore.c].
-
-
-
- 5
-
-
-
-
-
-
-
- 3.3 Freeze Level
-
- Note that the sp screen heading shows "freeze off".
- Enter f(2) (or freeze_at(2), if you prefer). Note that
- the heading now shows "freeze @2". This means all
- tasks at or below priority level 2 are frozen. Switch
- to the op screen (^s or Esc). Note that the idle task
- is not running (it has priority 0), but that suspender
- and idle are running (they have priority 3). Switch
- back to sp (^s or Esc). Note: Esc fails to exit
- because opcon has 0 priority and thus is frozen. Enter
- ^f. Note that the heading shows "freeze off". ^f
- again will toggle back to "freeze @2". With freeze
- off, return to op screen. Note that idle is running.
- Now Esc will exit.
-
-
- The mechanism for freezing is simple. The freeze level is the
- same as the priority of spcon. In freeze mode (set by f() or
- ^f), spcon loops on sp_pipe with no wait. Hence, equal or lower
- priority tasks cannot wrest the processor from spcon. Thus they
- are frozen and unable to run. However, since spcon is unlocked,
- higher priority tasks can preempt it and run. Freeze also has no
- effect upon isr's and lsr's. They run normally. Hence, for
- example, if you freeze @3 or above for too long, you will get a
- signal counter overflow from the ts semaphore because the timeout
- task is frozen. Also, it is important to remember that if
- running a debug version (e.g. ddemolv.exe), ticks are simulated
- by idle which has priority 0. Hence a freeze at any level shuts
- down all timing. Thus, freeze is not recommended for debug
- versions.
-
-
- 3.4 Trace Buffers
-
- There are three trace buffers: (1) call trace buffer (ctb), (2)
- task trace buffer (ttb), and (3) error buffer (eb).
-
- From the sp screen, enter sb(ctb). This shows the end
- of the call trace buffer (i.e. the most recent calls).
- Elapsed time (time) is on the left. Press End
- repetitively. Note that time keeps advancing. This is
- because trace is still on (look at the heading). Press
- ^t. Note "trace off" in the heading. Now hit End
- repetitively. Note that time stands still. Press
- Home. This goes to the beginning of ctb. Press Up
- Arrow and you can see the oldest entry on the top line.
- Hold Down Arrow down and you can scroll forward through
- ctb. PgDn and PgUp permit moving a page at a time.
- Strike t and you're in the task trace buffer; strike e
- and you're in the error buffer; strike c and you're
- back in the call trace buffer. Note that your last
- position in ctb has not changed.
-
-
-
- 6
-
-
-
-
-
-
-
- You can also display the task buffer with sb(ttb) and the error
- buffer with sb(eb) from the sb screen. Note that the last task
- in ttb is spcon and that it is running, as you would expect.
- Note also that the last call in ctb is pput_char 14 (^t) into
- sp_pipe -- i.e. the command which turned trace off (store_char is
- the lsr which does the putting). The quick switch capability (c,
- e, and t) combined with position retention allows you to easily
- compare information between trace buffers.
-
- Examine ttb and ctb in detail. You will see that these traces
- provide a lot of insight into how DOSdemo runs. The call trace
- mechanism is implemented in enter_ssrt() [spa.asm] which replaces
- enter_ssr if smxProbe is installed and if test mode. Task trace
- is implemented in the scheduler if test mode. Call trace is
- implemented in xesr.c if test mode.
-
- CAUTION: smx calls, which themselves make smx calls, do not show
- correct return values in ctb. For example, create_nmsg() calls
- _nmallocx(). The return value shown for create_nmsg() is
- meaningless; the return value for _nmallocx() is actually the
- return value for create_nmsg().
-
-
- 3.5 Call Triggering
-
- From the sp screen, enter tr(timeout). This resumes
- tracing and triggers on the first pass of any call from
- the timeout task, with any parameters. When the
- trigger occurs, information concerning the call is
- stored in ctb, trace is turned off, and the last page
- of ctb is displayed. Note that the specified task
- (i.e. timeout, in this case) appears on the last line
- of ctb. Go back to the sp screen (Esc). Enter
- tr(timeout,,10). This causes the same trigger, but on
- the 10th pass. Note the longer delay. Now try
- tr(,signal). This triggers on the first pass of signal
- from any task or lsr with any parameters. Do this
- repetitively (Esc, ^r (repeat)) -- you will see at
- least two different tasks appear on the last line of
- ctb. (Usually you will see keep_time, but
- occaisionally you will see disk_demo.) Try
- tr(,,,,INF). This triggers on the first pass of any
- call from any task or lsr with any parameters, except
- parameter 2 which must be INF. Look at ctb and pick
- other triggers to try. The command format is:
-
- tr(task,call,passes,par1,par2,par3)
-
- Don't leave out comma's! (except after the last
- argument you specify)
-
- Call triggering followed by examining the call trace is akin to
- instruction-level triggering with a code debugger or a logic
- analyzer followed by examining the instruction trace. This is a
- powerful debugging technique. It permits seeing what led up to a
-
- 7
-
-
-
-
-
-
-
- particular event (e.g. signaling a particular semaphore from a
- particular task). With call triggering, you are working at a
- high level -- i.e. the task level. (Presumably the code
- debugging phase is done.) Hence, this is a tool for tracking
- system-level and integration problems. It helps you to see how
- the tasks are interacting, what is and isn't running and when,
- the frequency of certain events, etc. Note that you can also
- look at the task trace and error buffers. These, too, are
- stopped. ttb provides a nice overview and a longer time span
- than ctb. eb, of course, shows errors which have occurred. It
- may cover a very long time span.
-
- The call trigger mechanism is implemented in call_trigger()
- [trig.c]. Call trigger detection is implemented in enter_ssrt()
- [spa.asm] along with call trace.
-
-
- 3.6 Executing smx Calls Directly
-
- From the sp screen enter stop(timeout,INF). Switch to
- the op screen (^s). Note that both timeout and
- suspender are stopped (suspender suspends itself, then
- is resumed by timeout. Go to sp and enter
- resume(suspender). Note that suspender's run count has
- increased by 1. Repeat (^s ^r ^s) and watch the
- suspender run count increment. Try start(timeout) and
- observe that both tasks are running again.
-
- In a similar manner, you can execute any smx call directly!
- Remember, however, that you are making calls from within the
- spcon task. Hence, it is probably not a good idea to do calls
- which will suspend or stop the current task (i.e. spcon). Note
- also that "ct" (current task) is not recognized (only fixed
- handle names can be entered into ht). The most useful smx calls
- for debugging are calls which act upon other tasks or objects
- such as stop(), start(), suspend(), resume(), bump_task(),
- signal(), etc.
-
- As an example of a probably-not-useful thing to do,
- enter pput_char(41,sp_pipe,0). This puts an 'A' (0x41)
- on the screen.
-
-
- 3.7 Error Trigger
-
- From the sp screen, enter start(errgen). Switch to op
- screen and look at the error messages. Switch back to
- sp screen and enter sb(eb) to look at the error buffer.
- Esc back to sp screen and enter tre(errgen,,20) to
- trigger on the 20th error from errgen. Now try tre().
- This triggers on any error. Try tre(,10). This picks
- up INVALID_QCB (errno == 10).
-
-
-
-
- 8
-
-
-
-
-
-
-
- As with call triggering, all three trace buffers are immediately
- stopped when the trigger event occurs. Hence, you can look at
- the history of smx calls and task runs in ctb and ttb. Error
- triggering allows you to capture any error, a particular error,
- any error from a particular task, or a particular error from a
- particular task. The error trigger mechanism is implemented in
- error_trigger() [trig.c]. Error trigger detection is implemented
- in display_error() [xesr.c].
-
- When you are done experimenting with triggering on
- errors, stop the errgen task with stop(errgen,INF).
-
-
- 3.8 Show Control Blocks
-
- From the sp screen, enter s(idle). This shows the idle
- tcb and its timer. Strike ^r repetitively and watch
- for changes. Enter s(ts) to see the ts semaphore.
- Note that the timeout task is waiting on it. Note the
- value of the handle of ts (e.g. 4750) and enter it.
- e.g. s(4750). This is another way to look at ts.
- NOTE: handles are always assumed to be hexadecimal
- numbers. Hence showv() is not necessary -- nor is "0x"
- -- as they are in a code debugger environment. Pick
- other smx objects to look at such as timeout,
- suspender, ticks, rq, errgen, nmsg, etc.
-
- show() may be used to look at any smx control block in formatted
- form. This is the same command as is used with code debuggers
- (see instructions for use with your code debugger for more
- information). Note that certain symbols such as "ct" and
- "rq_top" are interpreted only by the code debugger -- smxProbe
- cannot recognize them. Also constructs such as "idle->fl" are
- interpreted only by the code debugger, not by smxProbe. smxProbe
- can interpret only symbols entered into the handle table, ht.
- Hence, working without a code debugger can be somewhat limiting
- if you need to use show() extensively.
-
-
- 3.9 Show Queues
-
- From the sp screen, enter sq(rq) (or showq(rq) or
- showrq(), if you prefer). This shows the ready queue.
- Note that spcon is at level 4. Hit ^r repetitively and
- watch for changes. Try sq(idle). This also shows the
- ready queue, since idle is in it. Try sq(timeout).
- The timeout task spends most of its time waiting at the
- ts semaphore, so you should see it waiting at ts.
- Occaisionally, timeout is in the ready queue, so if you
- strike ^r many times, you will eventually catch timeout
- at level 3 in rq. A better way to see this is to
- strike ^f. This sets freeze @4. Now note that timeout
- is frozen at level 3 in rq. Enter f(2), then sq(rq).
- Note that spcon is at level 2, timeout is gone, but
- sleeper is frozen after spcon at level 2 (press ^r
-
- 9
-
-
-
-
-
-
-
- again, if spcon doesn't appear). Enter the value of a
- handle (e.g. sq(4750)). As with show, showqv() and 0x
- are unnecessary in this environment.
-
- showq() may be used to examine any smx queue in structured form.
- This is the same command as used with code debuggers -- see
- instructions for use with your code debugger for more
- information. Also, comments, above, with regard to show() apply
- here.
-
-
- 3.10 Starting in Freeze Mode
-
- Code debuggers normally come up with operation stopped at the
- entry point to the code under test. This allows setting a
- breakpoint or changing a variable. To achieve a similar startup
- with smxProbe, make sure that spcon is created with MAX priority
- and enable the INITIALIZATION FREEZE code in sp_init() [sp.c].
- Remake sp_.lib and ddemo_t.exe. This code has the effect of
- freezing all tasks after ainit() finishes. It then swaps to sp
- screen.
-
- Do the above, then run _ t. Note that the sp screen
- appears almost immediately. ^s, however, shows that
- demo_init() has run. If this is undesirable, move
- application initialization into a lower priority task
- started by ainit(). Then the freeze will occur before
- the application code has run. Now enter tr(timeout).
- Wait awhile. Observe that nothing happens because all
- tasks are frozen! Enter sq(rq) to see this. Now press
- ^f. Voila!
-
-
- 3.11 Target Operation
-
- smxProbe obviously requires a PC-compatible keyboard, monitor
- adapter, and monitor. If your target lacks these, input to
- sp_pipe can come from any source. Monitor output is directly
- written to a 2000 word buffer which can be anywhere in memory.
- If you have a debugger which can dump this to a screen in ASCII,
- you're in business.
-
- To permit debugging via a remote PC connected to a spare serial
- port on the target, we are considering splitting spcon into a
- control task and a display task inter-connected via a pipe. Then
- the keyboard handler and display task can be moved to the remote
- PC and the keyboard and display pipes, at both ends, can be
- linked via a serial channel.
-
-
-
-
-
-
-
-
- 10
-
-
-
-
-
-
-
- 4. TIPS
-
- 1. Problem: Trace not working
- Cause: Trigger turns trace off
- Solution: ^T
-
- 2. Problem: tr(task) never triggers, yet task is running
- (appears in ttb)
- Cause: Task makes no smx calls.
- Solution: Add an smx call if you need to trigger on
- this task.
-
- 3. Problem: Task appears in ttb, but not in ctb
- Cause: same as #2
-
- 4. Problem: Some smx calls are not appearing symbolically
- in ctb.
- Cause: Look at command_table[] in sp.c. Observe
- that most entries have been commented out.
- This is to prevent linking in unused smx
- calls.
- Solution: Remove "//" for those calls you are using.
-
- 5. Problem: BUILD_HT does not seem to be working in some
- cases. Symbolic names are not appearing for
- some handles.
- Cause: Handle table may be full.
- Solution: Increase HT_SIZE in sp.h and remake sp.
-
- 6. Problem: When stopping on a trigger, the trace buffers
- have time gaps in them.
- Cause: Trace was turned off when you set the
- trigger.
- Solution: ^t then tr() or ^r.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 11
-