Trace functions are functions for enabling a debugger to trace program execution. Execution trace is performed by setting hook routines.
Return from a hook routine must be made after states have returned to where they were when the hook routine was called. Restoring of registers, however, can be done in accordance with the C language function saving rules.
In a hook routine, limitations on states must not be loosened to make them less restrictive than when the routine was called. For example, if the hook routine was called during interrupts disabled state, interrupts must not be enabled.
A hook routine was called at protection level 0.
A hook routine inherits the stack at the time of the hook. Using too much stack may therefore cause a stack overflow. The extent to which the stack can be used is not definite, since it differs with the situation at the time of the hook. Switching to a separate stack in the hook routine is a safer option.
hsvc
Detail:
None
Sets hook routines before and after the issuing of a system call or extended SVC. Setting NULL in hsvc
cancels a hook routine.
The objects of a trace are T-Kernel/OS system calls (tk_???_???) and extended SVC. Depending on the implementation, generally tk_ret_int is not an object of a trace.
T-Kernel/DS system calls (td_???_???) are not objects of a trace.
A hook routine runs as a quasi-task portion of the task that called a system call or extended SVC for which a hook routine is set. Therefore, for example, the invoking task in a hook routine is the same as the task that invoked the system call or extended SVC.
Since task dispatching and interrupts can occur inside system call processing, enter()
and leave()
are not necessarily called in succession as a pair in every case. If a system call is one that does not return, leave()
will not be called.
FN |
fncd
| Function Codes < 0 System call ≧ 0 Extended SVC | |
TD_CALINF* |
calinf
| Caller information | |
...
| Parameters (variable number) |
typedef struct td_calinf { Information to determine the caller for the system call or extended SVC; it is preferable to include the information for the stack back-trace. The contents are implementation-dependent, but generally consist of register values such as stack pointer and program counter. } TD_CALINF;
enter
is called right before a system call or extended SVC.
The value passed in the return code is passed transparently to the corresponding leave()
. This makes it possible to pair enter()
and leave()
calls or to pass any other information.
exinf = enter(fncd, &calinf, ... ) ret = system call or extended SVC execution leave(fncd , ret, exinf)
For system call
The parameters are the same as the system call parameters.
For extended SVC
The parameters are as in the packet passed to the extended SVC handler.
fncd
is likewise the same as that passed to the extended SVC handler.
enter
is called right after returning from a system call or extended SVC.
When a hook routine is set after a system call or extended SVC is called (while the system call or extended SVC is executing), in some cases leave()
only may be called without calling enter()
. In such a case NULL is passed in exinf
.
If, on the other hand, a hook routine is canceled after a system call or extended SVC is called, there may be cases when enter()
is called but not leave()
.
hdsp
Detail:
None
Sets hook routines in the task dispatcher. Setting NULL in hdsp
cancels a hook routine.
The hook routines are called in dispatch disabled state. The hook routines must not invoke T-Kernel/OS system calls (tk_.) or extended SVC. T-Kernel/DS system calls (td_...) may be invoked.
ID |
tskid
| Task ID of the started or resumed task | |
INT |
lsid
|
Logical space ID of the task designated in tskid |
exec
is called when the designated task starts execution or resumes. At the time exec()
is called, the task designated in tskid
is already in RUNNING state and logical space has been switched. However, execution of the tskid
task program code occurs after the return from exec()
.
ID |
tskid
| Task ID of the executed or stopped task | |
INT |
lsid
|
Logical space ID of the task designated in tskid | |
UINT |
tskstat
|
State of the task designated in tskid |
stop
is called when the designated task executes or stops. tskstat
indicates the task state after stopping, as one of the following states:
TTS_RDY | READY state |
TTS_WAI | WAITING state |
TTS_SUS | SUSPENDED state |
TTS_WAS | WAITING-SUSPENDED state |
TTS_DMT | DORMANT state |
0 | NON-EXISTENT state |
At the time stop()
is called, the task designated in tskid
has already entered the state indicated in tskstat
. The logical space is indeterminate.
hint
Detail:
None
Sets hook routines before and after an interrupt handler is called. Hook routine setting cannot be done individually for different exception or interrupt factors. One pair of hook routines is set in common for all exception and interrupt factors.
Setting hint
to NULL cancels the hook routines.
The hook routines are called as task-independent portion (part of the interrupt handler). Accordingly, the hook routines can call only those system calls that can be invoked from a task-independent portion.
Note that hook routines can be set only for interrupt handlers defined by tk_def_int with the TA_HLNG attribute. A TA_ASM attribute interrupt handler cannot be hooked by a hook routine. Hooking of a TA_ASM attribute interrupt handler is possible only by directly manipulating the exception/interrupt vector table. The actual methods are implementation-dependent.
The parameters passed to enter()
and leave()
are the same as those passed to the exception/interrupt handler. Depending on the implementation, information other than dintno
may also be passed.
A hook routine is called as follows from a high-level language support routine.
enter(dintno); inthdr(dintno); /* exception/interrupt handler */ leave(dintno);
enter()
is called in interrupts disabled state, and interrupts must not be enabled. Since leave()
assumes the status on return from inthdr()
, the interrupts disabled or enabled status is indeterminate.
enter()
can obtain only the same information as that obtainable by inthdr()
. Information that cannot be obtained by inthdr()
cannot be obtained by enter()
. The information that can be obtained by enter()
and inthdr()
is guaranteed by the specification to include dintno
, but other information is implementation-dependent. Note that since interrupts disabled state and other states may change while leave()
is running, leave()
does not necessarily obtain the same information as that obtained by enter()
or inthdr()
.