![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Task and Multiprogram Debugging The Apex debugger provides extensive support for task and multiprogram debugging, both through the debugger GUI and the non-GUI debugger.
Note: Tasking support is provided only for Ada programs.
The following sections are included in this chapter:
- Managing Tasks (Ada only)
- Debugging Multiple Programs
Managing TasksFrom a debugging point of view, every program consists of one or more tasks. A main program is a task called the root. All other tasks in a program are declared or allocated either by the root task or by tasks that are in turn declared or allocated by the root task.
Every program has at least one task, called the root task. The name root is automatically assigned to the root task in a job.
Task Numbers
Every time a task is activated in a program, Apex assigns it a task number. Whenever the debugger displays information about a task, it also displays the corresponding task number. You can use this number to specify tasks when you issue various debugger commands.
When a program consists of multiple tasks, each task maintains its own call stack, and you can display each of these stacks individually. For more information on call stacks, see Call Stack.
The Apex debugger provides extensive support for tasking. Table 22 describes the debugger tasking commands. Each of these commands is discussed in detail in its own reference page in this manual.
The task action commands (kill task, resume task, suspend task, etc.) utilize the debugger task to modify the behavior of your tasking application. Executing one of these commands has the effect of queueing the command in the debugger task. When you start the application in motion, for example with the g command, the debugger task executes the queued commands.
The Tasks Window
You can display the status of all tasks in a program by displaying the Tasks window. To open the Tasks window, execute the Windows > Tasks or the editor Debug > Window > Tasks commands.
![]()
The following information is displayed for each task:
- Queue Number indicates the task's position on the run queue(Rn) or the delay queue (Dn) in the nth position. R1 runs next; the delay for D1 expires next. An asterisk indicates the current task (the breakpointed task or the most recent task).
- Task number assigned by Apex.
- Task name or a T followed by the name of the task type that declared the task.
- The status column shows the state of each task and additional information for some states. Possible task states are listed in the discussion of the lt command.
Viewing the Stack of the Current Task
When you are debugging a program with the Apex debugger, you can open the Stack window to view the stack of the current task. (The Stack window is described in Displaying the Call Stack.)
When a program has multiple tasks, each task maintains its own stack. You can display the stack for a particular task by selecting the task in the Tasks window.
When the Stack window is visible, it displays the task selected by the current context. The current context is the frame highlighted in the Stack window.
By default, the current frame is the topmost frame of whatever task has been stopped by the debugger. However, you can change the current context by selecting a different frame in the current task's stack or by selecting a different task in the Tasks window.
Referencing Task Activations
In the Tasks window, the number of each task appears first. The debugger numbers all tasks sequentially beginning with 1, which is the number of the main program. The Tasks window lists the numbers of all tasks.
When a name component follows a task identifier, the name component specifies some object declared in the specified task. A stack frame number can be included to reference a frame in the call stack for the specified task.
Displaying Stack Frames: An Example
To display the frames in the stack, follow a series of steps like this:
- 1 . To display the Tasks window, issue the Windows > Tasks command from any debugger window.
![]()
- 2 . Select the line corresponding to task 8. This line will become highlighted
- 3 . Next, choose the Windows > Stack command. Apex displays a Stack window
![]()
lt
Syntax
lt [all | use |task
| thread [thread_id
] | lwp [lwp_id
]]
Arguments
- all
Provides a detailed display for all tasks up to the maximum of 300 tasks.
- lwp
List information about the lightweight process layer.
- lwp_id
Address of lightweight process control block for which information is to be listed.
- task
Name or hexadecimal address of task for which detailed information is displayed. The current task is the breakpointed task or the most recent task. task can also be the decimal sequence number displayed in the output of the simple lt (no arguments) command.
- thread
List information about the thread layer.
- thread_id
Address of thread control block for which information is to be listed.
- use
Display the location and usage of stacks for all tasks up to the maximum of 300 tasks.
Description
If all, use, thread, lwp or a task is not specified, lt lists all active tasks (up to a maximum of 300) and gives a brief status for each one.
Display Status for All Active Tasks
The lt command displays the following columns of information for each task. The columns are labeled Q#, TASK, NUM, DEBUG STATUS and STATUS.
The Q# column (queue numbers) can have several values. Rn indicates that the task is on the run queue in the nth position. R1 runs next. Dn means that the task is on the delay queue in the nth position. The delay for D1 expires next.
Note: The queue position numbers are only applicable to the VADSmicro kernel. They are not displayed when Ada tasking is layered on other OS Threads.
An asterisk (*) indicates the current task (the breakpointed task or the most recent task).
The task that was executing when the program stopped will be indicated by an `*' in the Q# column. Its state will be shown as ready.
An Abnormal in the Q# column indicates the task has been aborted.
The TASK column contains either the name of the task or a T followed by the name of the task type that declared the task. Note that the main program's task has no name and is listed as <main program>. Also, the runtime defines a task which is used when all other tasks are suspended and the scheduler is waiting for an interrupt event. This task is listed as <idle task> if it is the breakpointed task. Otherwise, the idle task is not listed.
If the breakpointed task is not an Ada task or the idle task, this task is listed as <non-Ada task>.
A special signal task is created for each interrupt entry. It is given the name signal sig_num where sig_num is its interrupt vector number.
A special interrupt task is created for each attached ISR. It is given the name interrupt intr_num where intr_num is its interrupt vector number.
The NUM column contains the sequence number assigned to the task. This number is always 1 for the main task and is incremented every time a task is created. This number is used when setting breakpoints for a particular task. The number can also be used with the lt command to specify the task (lt 5). The tcb address of the task can be displayed by getting a full listing of the task using the lt task command.
The DEBUG STATUS column shows the debugger's interaction with each task. If the debugger has not altered the state of the task, then the status is "running". Times displayed are absolute time, which start with 0 unless the timer is reset.
The STATUS column shows the state of each task and additional information for some states. Times displayed are absolute time, which start with 0 unless the timer is reset via the package Calendar or package Xcalendar. The time must match Calendar.Clock. The possible states for each task are listed in the following table.
State Description
not yet active The task is created but not activated. See Ada LRM 9.3
ready to start The task is activated and ready to start its first execution.
awaiting activations Parent task suspended while waiting for child tasks to complete their activation.
awaiting terminations Parent task suspended while waiting for child tasks to terminate.
executing The task is executing
ready The task is on the run queue.
suspended at accept The task executes an accept on an entry that no task is currently calling, so is waiting until a task calls it.
For entry entry_name produces name of
accepting entry
suspended at fast accept The task executes a 'fast' accept on an entry that no task is currently calling, so is waiting until a task calls it.
For entry entry_name produces name of
accepting entry
suspended at call The task executes an entry call and remains in this state until transition to in rendezvous state
task_name
[task_addr
].entry_name
gives target task and entry
suspended at select The task executes a select but no tasks are calling open entries; statement has an open terminate alternative a nd is waiting until some event enables it to proceed.
(terminate possible)
Task termination conditions satisfied.
(terminate not possible)
Task terminate conditions not satisfied; waiting for child tasks to terminate.
OPEN ENTRIES: entry_name
Lists each open entry of select.
NO ENTRIES OPEN:
No entries currently open.
in rendezvous The task is in rendezvous with the called task.
task_name
[task_addr
].entry_name
gives target task and entry
attempting rendezvous The task is attempting to rendezvous with the called task.
task_name
[task_addr
].entry_name
gives target task and entry
finished rendezvous The task has just finished its rendezvous with the called task.
task_name
[task_addr
].entry_name
gives target task and entry
suspended at delay The task executes a delay statement.
suspended at passive call or cond wait The task is suspended calling a passive task's entry whose guard is closed or the task is waiting on an Abort_Safe condition variable.
finished passive call or cond wait The task suspended at a passive call has been resumed. The guard for the called entry has changed from closed to open. Alternatively, if the task was waiting on an Abort_Safe condition variable, the condition variable has been signalled.
suspended on semaphore Task blocked waiting for its semaphore to be signalled.
[semaphore_addr]
gives semaphore ID
suspended on mutex Task blocked from entering critical region protected by a mutex. Another task has locked the mutex.
[mutex_addr] gives mutex ID
suspended on cond Task blocked waiting for its condition variable to be signalled.
[cond_addr] using mutex [mutex_addr]
gives condition variable and mutex IDs.
waiting to exit main program suspended, waiting for child tasks to terminate.
completed The task executes all its code body. Upon completion of all subtasks, it terminates. See Ada LRM 9.4(5)
terminated The task terminates. See Ada LRM 9.4(6)
destroyed The task has been terminated and is in the process of being destroyed.
waiting for signal The task created for the interrupt entry is waiting to be signalled by its interrupt handler. After being signalled, this task does an entry call to the interrupt entry in the attached task.
attached to task_name[task_addr] at entry entry_name
gives attached task and interrupt entry
waiting for interrupt The task created for the interrupt vector is waiting to be signalled by its interrupt handler. After being signalled, this task calls the attached interrupt service routine (ISR). The task is blocked at a sigwait() for the attached OS signal.
handler at handler_addr
gives the address of the ISR
suspended at absolute delay The task is delaying until specified date/time
+ suspend The task is in the indicated state and has also been explicitly suspended
+ delay The task is on the delay queue and is in the indicated state (the task is executing a timed wait operation, such as a wait for a semaphore)
+ pend The task is in the indicated state and is also pending on a semaphore. This state occurs when a task blocks on the semaphore guarding a passive task.
Additional information can be appended to the status entry.
in rendezvous withtask_name
[task_addr
] at entryentry_name
means that the task accepted the entry call from the named task at the named entry. This message can occur more than once. It repeats for each rendezvous resulting from outer nested accepts in order from innermost to outermost accept.
on delay queue, until day:number
sec:number
means that after the runtime current_time reaches the given day and duration seconds, this task is ready for execution. The task can be on the delay queue because of a simple delay statement, a timed entry call, or because of an open delay alternative of an active select.
If a task was executing a delay when the program stopped, the amount of time left in the delay at the time of the lt command is indicated. The amount of time left is updated on any subsequent lt commands while the program is stopped. If the delay expires, the debugger indicates that the task is no longer on the delay queue.
about to raiseexception_string
means that an exception occurs in the called task during a rendezvous and the named exception is raised in the master.
The lt command produces output like that in this abbreviated example:
Q# TASK NUM STATUS rand_delay 14 suspended at accept for entry rand T philosopher 13 in rendezvous T output[2].put_cursor R1 T philosopher 12 ready R2 T philosopher 11 ready R3 T philosopher 10 ready R4 T philosopher 9 ready T fork 8 suspended at fast accept for entry pick_up T fork 7 suspended at fast accept for entry pick_up T fork 6 suspended at fast accept for entry pick_up T fork 5 suspended at fast accept for entry pick_up T fork 4 suspended at fast accept for entry pick_up T dining_room 3 suspended at select open entries: allocate_seat leave * T output 2 executing in rendezvous with T philosopher[13] at entry put_cursor <main program> 1 awaiting terminationsWhen tasks are dynamically created (that is, anonymous tasks), only their identifiers (the address of the task control block) are listed. Use the task number with the task and call stack commands.
Using the lt command to display tasks using the fast rendezvous optimization has a few subtle differences.
Display Single Task Status
The lt task form of this command provides additional information about a single task. For example lt dining_room produces the following output.
>lt dining_room => a task type has no address (a task object does): dining_room Q# TASK NUM STATUS T dining_room 3 suspended at select ENTRY STATUS TASKS WAITING allocate_seat open - no tasks waiting - enter - no tasks waiting - leave open - no tasks waiting - waiting to execute fast rendezvous in a calling task thread id = 01007d3a0 thread status = PT_CWAIT Ada tcb address = 01007d1c6 static priority = 0 current priority = 0 parent task: <main program>[1]
The first lines are the same as the brief display. The added information includes a table of entry queue status giving the entry name, whether the entry is open for a select and the ordered lists of the tasks waiting at that entry.
The thread ID gives the ID of the underlying OS thread. For the VADSmicro kernel, it is the address of its micro kernel task control block.
The tcb address line indicates the address the runtime system assigned to the task when it was created. You can use the address value when identifying instances of a task type, as the task type name is not a unique identifier. An address of 00000000 is displayed for idle_task or non-Ada task since they are not real Ada tasks.
The static priority line gives the task priority. Following that is current priority. A task executes at the higher of its own static priority and the current priority of any task with which it is in rendezvous.
For the VADSmicro kernel, if the task's thread priority differs from the current priority, the thread priority is displayed on the line following the current priority.
The parent task line describes the master of this task. The task that is executing this master is [1] With this information it is possible to construct a tree of tasks, linked by their masters to their parent tasks. Note that the task executing the master is not necessarily the task that creates it.
Note that, if applicable, the thread status is also listed. For example:
>lt 1004e92c Q TASK ADDR STATUS R c 01004e92c ready thread id = 01004eaa0 thread status = PT_RUN static priority = 0 current priority = 0 parent task: <main program>[01001f3fc] >
The system clock can continue to run while the debugger is suspended at a breakpoint waiting for input. This causes delays to expire immediately when stepping away from the breakpoint and the flow of program control to relate to breakpoints and their timing in an unpredictable fashion.
If time slicing is enabled, a breakpoint is often followed by a time slicing transfer of control. This transfer is pathologic if a breakpoint is set in the actual time slicing logic in the Apex kernel such as in Switch or Switch_To. The time slice response calls Switch and reaches another breakpoint. The delay in handling the breakpoint uses up the time slice and so another time slicing interrupt comes just as execution resumes from this breakpoint. For this reason, it is convenient when debugging tasks to configure the runtime system without time slicing enabled
v_usr_conf.configuration_table.time_slicing_enabled := false;
or to call the subprogram in V_Xtasking to turn off time slicing.
v_xtasking.set_time_slicing_enabled(false);
Warning: Breakpoints in the runtime system can leave the tasking data structures in an unpredictable state. Output from the lt command may then be questionable, particularly for the current task. For example, a commonly used breakpoint is Switch_To, which is called when control transfers to a new task. At this point, in the middle of an accept, rendezvous information may not be consistent.
Display Stack Usage and Location
The lt use form of this command displays the location and usage of the task stacks. It displays the same information for the kernel and interrupt stacks.
The command, lt use, produces this abbreviated output:
>lt use Q# TASK NUM STATUS rand_delay 14 suspended at accept for entry rand wait stack: 0100b7720 .. 0100b86bf, used 499 out of 4000 [12%] stack: 0100b4f50 .. 0100b86ef, used 4368 out of 14240 [30%] exception stack: 0100b3bc8 .. 0100b4f4f, used 4962 out of 5000 [99%] T philosopher 13 in rendezvous T output[2].put_cursor wait stack: 0100b27f0 .. 0100b378f, used 443 out of 4000 [11%] stack: 0100b0020 .. 0100b37bf, used 4699 out of 14240 [32%] exception stack: 0100aec98 .. 0100b001f, used 4962 out of 5000 [99%] R1 T philosopher 12 ready wait stack: 0100ad8c0 .. 0100ae85f, used 1120 out of 4000 [28%] stack: 0100ab0f0 .. 0100ae88f, used 4643 out of 14240 [32%] exception stack: 0100a9d68 .. 0100ab0ef, used 4962 out of 5000 [99%] R2 T philosopher 11 ready wait stack: 0100a8990 .. 0100a992f, used 443 out of 4000 [11%] stack: 0100a61c0 .. 0100a995f, used 5472 out of 14240 [38%] exception stack: 0100a4e38 .. 0100a61bf, used 4962 out of 5000 [99%] R3 T philosopher 10 ready wait stack: 0100a3a60 .. 0100a49ff, used 443 out of 4000 [11%] stack: 0100a1290 .. 0100a4a2f, used 9776 out of 14240 [68%] exception stack: 01009ff08 .. 0100a128f, used 4962 out of 5000 [99%] R4 T philosopher 9 ready wait stack: 01009eb30 .. 01009facf, used 443 out of 4000 [11%] stack: 01009c360 .. 01009faff, used 14080 out of 14240 [98%] exception stack: 01009afd8 .. 01009c35f, used 4962 out of 5000 [99%] T fork 8 suspended at fast accept for entry pick_up wait stack: 010099c00 .. 01009ab9f, used 443 out of 4000 [11%] stack: 010097430 .. 01009abcf, used 4611 out of 14240 [32%] exception stack: 0100960a8 .. 01009742f, used 4962 out of 5000 [99%] T fork 7 suspended at fast accept for entry pick_up wait stack: 010094cd0 .. 010095c6f, used 443 out of 4000 [11%] stack: 010092500 .. 010095c9f, used 4611 out of 14240 [32%] exception stack: 010091178 .. 0100924ff, used 4962 out of 5000 [99%] T fork 6 suspended at fast accept for entry pick_up wait stack: 01008fda0 .. 010090d3f, used 2368 out of 4000 [59%] stack: 01008d5d0 .. 010090d6f, used 4611 out of 14240 [32%] exception stack: 01008c248 .. 01008d5cf, used 4962 out of 5000 [99%] T fork 5 suspended at fast accept for entry pick_up wait stack: 01008ae70 .. 01008be0f, used 443 out of 4000 [11%] stack: 0100886a0 .. 01008be3f, used 6720 out of 14240 [47%] exception stack: 010087318 .. 01008869f, used 4962 out of 5000 [99%] T fork 4 suspended at fast accept for entry pick_up wait stack: 010085f40 .. 010086edf, used 443 out of 4000 [11%] stack: 010083770 .. 010086f0f, used 11024 out of 14240 [77%] exception stack: 0100823e8 .. 01008376f, used 4962 out of 5000 [99%] T dining_room 3 suspended at select wait stack: 010081010 .. 010081faf, used 499 out of 4000 [12%] stack: 01007e840 .. 010081fdf, used 4699 out of 14240 [32%] exception stack: 01007d4b8 .. 01007e83f, used 4962 out of 5000 [99%] * T output 2 executing wait stack: 01007c0e0 .. 01007d07f, used 3200 out of 4000 [80%] stack: 010079910 .. 01007d0af, used 6973 out of 14240 [48%] exception stack: 010078588 .. 01007990f, used 4962 out of 5000 [99%] <main program> 1 awaiting terminations wait stack: 07fffb680 .. 07fffc61f, used 3986 out of 4000 [99%] stack: 07fdfb690 .. 07fffc62f, used 5295 out of 2101152 [0%] exception stack: 07fdfa308 .. 07fdfb68f, used 0 out of 5000 [0%]
KERNEL stack: 0806ff000 .. 0806fffff, used 48 out of 4096 [1%] INTERRUPT stack: 0806fd7d0 .. 0806fefff, used 32 out of 6192 [0%] INTERRUPT exception stack: 0806fd000 .. 0806fd7cf, used 0 out of 2000 [0%] KERNEL heap: 08005b298 .. 0806effff, used 666984 out of 6901096 [9%]The lt use command displays a normal stack memory address range and exception stack range. The exception stack is located directly below the normal stack area. This is needed for execution of the exception unwinding logic to handle the stack limit Storage_Error exception. Notice that the size of the exception stack is the same for all tasks.
Also notice that the size of the task stacks has been increased by the configuration table parameter, Wait_Stack_Size. The wait stack area is allocated at the top of the task stack. The wait stack is needed to support the fast rendezvous optimization.
For each task stack range lt use calculates stack usage by starting at the Low_Address memory location and searching upward for the first byte not containing the target-specified fill character, typically 0, but 16#EE# for VxWorks and 16#FF# for LynxOS. The following equations are used:
stack_size := (high_address + 1) - low_address bytes_used := (high_address + 1) - first_nonzero_address [usage %] := (bytes_used / stack_size) * 100
For Apex Cross systems, the lt use command displays the stack location and usage for the following system wide stacks: kernel, interrupt and interrupt exception.
The final line of the lt use command shows the location and usage of the kernel heap area. Observe that the system wide stacks and the main program task stack are pre-allocated directly above the kernel heap area. All the other task stacks are allocated from the kernel heap area. Allocation starts at the heap Low_Address.
It calculates heap usage by starting at the High_Address memory location and searching downward for the first byte that does not match the target specific fill character. The following equations are used:
heap_size := (high_address + 1) - low_address bytes_used := (first_nonzero_address + 1) - low_address [usage %] := (bytes_used / heap_size) * 100
Warning: Stack usage information can be incorrect for applications having dynamic task creation and completion. When a task completes, its stack area returns to a stack free list. Subsequent tasks attempt to get their stack areas from this free list. By default, we chose to optimize task creation and completion processing by not initializing the task stack areas. Initializing of stacks can be enabled in the configuration table located in the v_krn_conf package body for Apex Cross or the v_usr_conf package body for Apex Native:
Zero_Stacks_Enabled => False
Note that the fast rendezvous Wait_Stack is contained within the normal stack as follows:
![]()
The amount of stack available for task execution as specified by the Default_Task_Stack_Size in the v_usr_conf package or modified by using T'Storage_Size or pragma Storage_Size. The Wait_Stack and Exception_Stack are implicitly added to the stack size requested.
The Wait_Stack is used as temporary register space when initializing a task. For this reason a small amount of the Wait_Stack is erroneously displayed as "used" even when Zero_Stacks_Enabled is set to True. We chose to optimize task creation by not initializing out the Wait_Stack.
Warning: We assume that values pushed on the stack are not equal to the fill value.
Display Thread and Lightweight Process Information (if applicable)
The lt thread [thread_id] and lt lwp [lwp_id] forms of this command display information from the control blocks of the underlying threads and lightweight process layers. The lt thread [thread_id] command is used to list information from the threads layer which lies directly beneath the Ada tasking layer. The lt lwp [lwp_id] command is used to list information from the lightweight process layer which lies directly beneath the thread layer.
If thread_id or lwp_id is not present, information from all of the control blocks is listed. If it is present, only information from the control block whose address is indicated in the command argument is listed.
The format of the information is target-dependent.
lu
List UNIX processes (/proc interface)
Syntax
lu [PID
]
Arguments
Description
lu provides a description of the process(es) the debugger is attached to.
If no arguments are listed, a brief description of all the processes the debugger is attached to is displayed.
>lu 24600: stopped by the debugger. 24599: stopped by the debugger. 24598: stopped on signal "trap" (5).
If a PID is listed following the command, the debugger prints a detailed description of the process whose process ID (PID) is given.
>lu 24600 pid 24600, utime 0 sec, stime 0 sec ppid 24598, group id: 24596, session id: 0 FLAGS: stopped [PR_STOPPED] stopped on an event of interest [PR_ISTOP] inherit-on-fork flag set [PR_FORK] run-on-last-close flag set [PR_RLC] stopped in response to stop directive, normally PIOCSTOP
Additional Tasking Commands
Note: These commands are only valid with Ada programs.
A number of additional task commands are available. The Suspend Task, Kill Task and Resume Task operations can be executed from the Tasks Window. Simply highlight the desired task and select the operation to be performed, either from the Tasks menu or the hot buttons.
The following additional tasking commands are available in the Command Pane or the non-GUI debugger.
priority task
Change task priority (Ada only)
Syntax
priority tasktask_id new_priority
Arguments
- new_priority
An integer value in the range of 0 to System.Priority'Last-1.
- task_id
Task identifier. This identifier can be the name of the task, the decimal task sequence number found in the NUM column of output from the simple lt command or the hexadecimal number indicating the task's tcb address. The tcb address can be found using the lt task_name command.
Description
The priority command sets the priority of the specified task to
new_priority
. Note that the word task is a required part of the syntax.In Screen Mode
Precede this command with : and follow with Return.
suspend task
Syntax
suspend tasktask_id
(Ada only)
Arguments
- task_id
A task identifier. This identifier can be the name of the task, the decimal task sequence number found in the NUM column of output from the simple lt command or the hexadecimal number indicating the task's tcb address. The tcb address can be found using the lt task_name command.
Description
The suspend command suspends the specified task.
In Ada tasking, the suspended task will be able to move to the ready queue, but will not be allowed to execute. Note that this is different than the normal suspended states of a task.
In Screen Mode
Precede this command with : and follow with Return.
resume task
Syntax
resume tasktask_id
(Ada only)
Arguments
- task_id
Task identifier. This identifier can be the name of the task, the decimal task sequence number found in the NUM column of output from the simple lt command or the hexadecimal number indicating the task's tcb address. The tcb address can be found using the lt task_name command.
Description
In Ada, the resume task command causes the specified suspended task to be resumed. The specified task must be a task which was suspended using the suspend program task command.
In Screen Mode
Precede this command with : and follow with Return.
kill task
Syntax
kill [tasktask_id
|pid
| all]
Arguments
- pid
Process identification number of the program to be killed. The PID can be obtained using the ps command outside of the debugger or the lp command from within the debugger.
- task_id
Task identifier of the task to be killed. This identifier can be the name of the task, the decimal task sequence number found in the NUM column of output from the simple lt command or the hexadecimal number indicating the task's tcb address. The tcb address can be found using the lt task_name command.
Description
The kill command kills a program or task. No parameters are necessary if only one task is being debugged. In this case, the current task is killed. Once all tasks in a debugging session have been killed or detached, only the quit and attach commands can be used.
In Screen Mode
Precede this command with : and follow with Return.
select task
Syntax
select tasktask_id
(Ada only)
Arguments
- task_id
Task identifier. This identifier can be the name of the task, the decimal task sequence number found in the NUM column of output from the simple lt command or the hexadecimal number indicating the task's tcb address. The tcb address can be found using the lt task_name command. (Ada only)
Description
The select task command, without a specified task, displays the current task.
The select task task_id command identifies a task to become the new current task. The call stack commands operate on the current task's call stack. If task_id is 0, the current task is displayed.
In Screen Mode
Precede this command with : and follow with Return.
Debugging Multiple ProgramsMultiple program debugging is a general term that describes several debugging situations. Multiple program debugging is available for all languages supported by Apex.
There are two main situations covered by the term Multiple Program Debugging. These are:
- 1 . The control of several independent processes by one debugger. These processes may be running on different targets (cross targets) or on the same target (multiple processes running on the same self target).
The debugger switches between debugging each program using the select program command.
This is dealt with in Simultaneous Programs and in the Rational Exec Programming Manual see the Multiple Target chapter.
- 2 . The control of separately loaded cooperating programs on a single target.
This feature is currently restricted to cross targets only. The separately loaded programs can be considered as part of the same program with a linkage which does not depend on the addresses at which the programs are loaded.
An example of such a program group is an Ada tasking program and the runtime kernel which communicate via a fixed interface. Another example is two Ada programs which communicate using the bind_object, resolve_object and inter_program_call services whose use is described in Programming for Rational Exec, Multiple User Programs.
This is dealt with below in Cooperating Multiple Programs
Simultaneous Programs
From the GUI, multiprogram debugging can be invoked by selecting the Multi-program debugging check box from the Debug dialog or the Run dialog (this option appears after both Debug and Debug Set Options have been selected.)
Users can debug multiple programs via the command line and/or from within the debugging session.
From the command line, users can invoke the debugger using the -program_file option followed by the name of the debugger configuration file to use.
rdboptions
-program_fileconfiguration_file_name
For native Apex products, the configuration file contains the executable names and arguments separated by the word "program".
For example, if you want to debug the three programs:
and you want to insert a comment in the configuration file, your configuration file will contain:
# this is a comment! program executable: foo executable_args: -a -b -c program executable: hello executable_args: -baz program executable: goodbye
If you name this file config_file, then invoke the debugger using the following command:
rdb -program_file config_file
The programs listed above will be debugged.
Once in a debugging session, you may debug additional running programs using the Attach command. Each use of the Attach command brings in another program that the user can debug in the single debugging session.
Note: You are not limited to one method of multiple program debugging, that is, the -program_file command line option and the attach command can be used in conjunction.
Current program
The current program is the program that the debugger is currently focused on. User's select the current program using the select program command. Most debugger commands apply only to the current program. The following debugger commands have been augmented to allow the command to be applied to one or more programs, and not necessarily to the current program.
Continue Rerun Kill Release Stop Suspend
Event Announcements
When an event occurs in any program the debugger announces the event, but does not effect any of the other programs. Events are announced as they arrive. However, if an event arrives when the debugger is busy - that is, executing a command, the debugger finishes the command and then announces the event.
Multiprogramming Commands
Table 23 lists the debugger commands as they apply multiprogram debugging.
The Programs Window
The Programs window provides access to the multiprogramming capabilities of the debugger. The format of the entries in this window is as follows:
program_number pid ppid attach_status status executable_name
An example of a Programs window is displayed below.
![]()
Command-Line Interface to Multiprogramming
The following commands can be entered either in the non-GUI debugger or in the Command Pane of the debugger GUI.
The g (continue), r (run) and stop (commands) are discussed in Controlling Execution.
attach
Syntax
attachpid program_name
attachprogram_name pid
Arguments
- pid
Process identification number of the running program to be attached to. The PID can be obtained using the ps command outside of the debugger.
- program_name
Description
The attach command attaches to an already running program. Note that both the process identification number (PID) and the name of the program to be attached to must be specified.
The -a pid command line option has the same effect as the attach command.
In Screen Mode
Precede this command with : and follow with Return.
detach
Syntax
detach [pid
| programprogram_id
] detach all
Arguments
- program_id
Identifier of the program to be detached.
program_id
can be the name or number of the program. Both of these values can be found using the lp command.- pid
Process identification number of the program to be detached. The PID can be obtained using the ps command outside of the debugger or the lp command from within the debugger.
Description
The detach command detaches a program from the debugging session. The detached program is no longer debugged, but not killed by the debugger.
No parameters are necessary if only one program is being debugged. In this case, the current program is detached.
If more than one program is being debugged and you want to detach all programs, use detach all. If you only want to detach one program, then you must use detach program program_id or detach pid.
If you want to detach the current program, first select a new current program then issue the detach program program_id command to the desired program.
When all programs in the debugging session are detached or killed, only the quit and attach commands are available for use.
In Screen Mode
Precede this command with : and follow with Return.
kill program
Syntax
kill [pid
| program program_id] kill all
Arguments
- pid
Process identification number of the program to be killed. The PID can be obtained using the ps command outside of the debugger or the lp command from within the debugger.
- program_id
Identifier of the program to be killed. program_id can be the name or number of the program. Both of these values can be found using the lp command.
Description
The kill command kills a program. No parameters are necessary if only one program is being debugged. In this case, the current program is killed. If more than one program is being debugged and you want to kill all programs, use kill all. If you only want to kill one program, then you must use kill program program_id or kill pid. Note that you cannot kill the current program in this case, you must first select a new current program and then kill the desired program.
Once all programs in a debugging session have been killed, only the quit command can be used.
In Screen Mode
Precede this command with : and follow with Return.
lp
Syntax
lp [program_id
] [all]
Arguments
- all
Provide a detailed display for all programs.
- program_id
Identifier of the program to be displayed. program_id can be the name or number of the program. Both of these values can be found using the lp command without arguments.
Description
This command displays information about the programs in a debugging session. If a program name or number is specified, lp displays information on that program. If a program is not specified, lp displays information about all programs.
The following information is displayed using the simple lp command:
>lp P# PID PPID ATTACH STATUS SUSPEND EXECUTABLE NAME 1 9581 0 false stopped false /usr/ada/self_d/fork1 <> 2* 9583 0 false stopped false /usr/ada/self_d/hello <>In this example, the attach commands were not used to debug the programs fork1 and hello. In addition, none of the programs are suspended, so all programs will be set in motion with the next continue or run command.
A * after the program number column indicates the current program (that it, the breakpointed program or the program most recently selected via the select program program command).
resume program
Syntax
resume program
[program_id]
Arguments
- program_id
Identifier of the program to be resumed. program_id can be the name or number of the program. Both of these values can be found using the lp command.
Description
The resume program command resumes a program for execution via the next continue or run command. If no program id is specified, the current program is resumed.
In Screen Mode
Precede this command with : and follow with Return.
select program
Syntax
select program [program_id
]
Arguments
- program_id
Identifier of the program to be displayed. program_id can be the name or number of the program. Both of these values can be found using the lp command.
Description
The select program command, without a program, displays the current program.
The select program program_id command causes the specified program to become the current active program.
When the select program program_id command is executed, the current program is deselected before the specified program becomes the new current program. The state of the deselected program is stored so that if it is reselected before the program is further executed, the current frame will be the same as it was when the program was deselected.
In Screen Mode
Precede this command with : and follow with Return.
suspend program
Syntax
suspend programprogram_id
Arguments
- program_id
The name or number of the program to be suspended. The program name and program number are found using the lp command.
Description
The suspend command suspends the specified program.
In the multiple-program debugger, the program is not set in motion by the r or g commands until it is resumed (by the resume program command).
In Screen Mode
Precede this command with : and follow with Return.
Cooperating Multiple Programs
This currently applies to cross runtimes using the Rational Exec only.
An example of this style of programming is given in the Programming for Rational Exec Manual, Multiple User Programs.
Briefly, the separate programs are linked to be loaded at different(non-overlapping) addresses and will communicate using runtime services.
In order to enable debugging of multiple programs of this sort,
the shell environment variable (Apex Session Switch) APEX_MULTIPROGRAM should be set before invoking the debugger.
From an Apex directory viewer, select Tools > Session > Environment and in the Environment dialog box, set Name: to APEX_MULTIPROGRAM and Value: to True.
From a shell window, use the UNIX command for your shell. For example, for the cshell setenv APEX_MULTIPROGRAM True.
Invoke the debugger to debug the main program of the group - the program which will execute first.
In the debugger, use the load command to load the other program(s).
In APEX_MULTIPROGRAM mode, the debugger will attempt to find the Apex views for the successive loaded programs and add them to the library configuration. Each program will be assigned a sequence number starting at 1.
You can then navigate around the various programs in the normal way.
The lp [all | id] command (or Programs window) will list the loaded programs.
The format will differ as described in the command description.
Output from the lt (list tasks) and lb (list breakpoints) commands will reflect the multiprogram configuration as will the Tasks and Breakpoint windows. Tasks and breakpoints will be ordered by the program id.
Rational Software Corporation http://www.rational.com support@rational.com techpubs@rational.com Copyright © 1993-2002, Rational Software Corporation. All rights reserved. |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |