[OpenVMS documentation]
[Site home] [Send comments] [Help with this site] [How to order documentation] [OpenVMS site] [Compaq site]
Updated: 11 December 1998

OpenVMS Debugger Manual


Previous Contents Index

17.6.4 Monitoring Task Events

The SET BREAK/EVENT and SET TRACE/EVENT commands enable you to set breakpoints and tracepoints that are triggered by task and exception events. For example, the following command sets tracepoints that trigger whenever task CHILD or %TASK 2 makes a transition to the RUN state:


DBG> SET TRACE/EVENT=RUN CHILD,%TASK 2

When a breakpoint or tracepoint is triggered as a result of an event, the debugger identifies the event and gives additional information.

The following tables list the event-name keywords that you can specify with the SET BREAK/EVENT and SET TRACE/EVENT commands:

Table 17-6 Generic Low-Level Task Scheduling Events
Event Name Description
RUN Triggers when a task is about to run.
PREEMPTED Triggers when a task is being preempted from the RUN state and its state changes to READY. (See Table 17-3.)
ACTIVATING Triggers when a task is about to begin its execution.
SUSPENDED Triggers when a task is about to be suspended.

Table 17-7 DECthreads-Specific Events
Event Name Description
HANDLED Triggers when an exception is about to be handled in some TRY block.
TERMINATED Triggers when a task is terminating (including by alert or exception).
EXCEPTION_TERMINATED Triggers when a task is terminating because of an exception.
FORCED_TERM Triggers when a task is terminating due to an alert operation.

Table 17-8 Ada-Specific Events
Event Name Description
HANDLED Triggers when an exception is about to be handled in some Ada exception handler, including an others handler.
HANDLED_OTHERS Triggers only when an exception is about to be handled in an others Ada exception handler.
RENDEZVOUS_EXCEPTION Triggers when an exception begins to propagate out of a rendezvous.
DEPENDENTS_EXCEPTION Triggers when an exception causes a task to wait for dependent tasks in some scope (includes unhandled exceptions, 1 which, in turn, include special exceptions internal to the DEC Ada Run-Time Library; for more information, see the DEC Ada documentation). Often immediately precedes a deadlock.
TERMINATED Triggers when a task is terminating, whether normally, by an abort statement, or by an exception.
EXCEPTION_TERMINATED Triggers when a task is terminating due to an unhandled exception. 1
ABORT_TERMINATED Triggers when a task is terminating due to an abort statement.


1 An unhandled exception is an exception for which there is no handler in the current frame or for which there is a handler that executes a raise statement and propagates the exception to an outer scope.

In the previous tables, the exception-related events are included for completeness. Only the task events are discussed in the following paragraphs. For more information about the exception events, see the debugger's online help (type Help Language_Support Ada).

You can abbreviate an event-name keyword to the minimum number of characters that make it unique.

The event-name keywords that you can specify with the SET BREAK/EVENT or SET TRACE/EVENT command depend on the current event facility, which is either THREADS or ADA in the case of task events. The appropriate event facility is set automatically when the program is brought under debugger control. The SHOW EVENT_FACILITY command identifies the facility that is currently set and lists the valid event name keywords for that facility (including those for the generic events).

Several examples follow showing the use of the /EVENT qualifier:


DBG> SET BREAK/EVENT=PREEMPTED
DBG> GO
break on THREADS event PREEMPTED 
  Task %TASK 4 is getting preempted by %TASK 3
   .
   .
   .
DBG> SET BREAK/EVENT=SUSPENDED
DBG> GO
break on THREADS event SUSPENDED 
  Task %TASK 1 is about to be suspended
   .
   .
   .
DBG> SET BREAK/EVENT=TERMINATED
DBG> GO
break on THREADS event TERMINATED 
  Task %TASK 4 is terminating normally
DBG>

The following predefined event breakpoints are set automatically when the program is brought under debugger control:

Ada examples of the predefined and other types of event breakpoints follow.

Example of EXCEPTION_TERMINATED Event

When the EXCEPTION_TERMINATED event is triggered, it usually indicates an unanticipated program error. For example:


...
break on ADA event EXCEPTION_TERMINATED 
  Task %TASK 2 is terminating because of an exception 
    %ADA-F-EXCCOP, Exception was copied at a "raise;" or "accept" 
    -ADA-F-EXCEPTION, Exception SOME_ERROR 
    -ADA-F-EXCRAIPRI, Exception raised prior to PC = 00000B61 
DBG> 

Example of DEPENDENTS_EXCEPTION Event (Ada)

For Ada programs, the DEPENDENTS_EXCEPTION event often unexpectedly precedes a deadlock. For example:


...
break on ADA event DEPENDENTS_EXCEPTION 
  Task %TASK 2 may await dependent tasks because of this exception: 
    %ADA-F-EXCCOP, Exception was copied at a "raise;" or "accept" 
    -ADA-F-EXCEPTION, Exception SOME_ERROR 
    -ADA-F-EXCRAIPRI, Exception raised prior to PC = 00000B61 
DBG> 

Example of RENDEZVOUS_EXCEPTION Event (Ada)

For Ada programs, the RENDEZVOUS_EXCEPTION event enables you to see an exception before it leaves a rendezvous (before exception information has been lost due to copying the exception into the calling task). For example:


...
break on ADA event RENDEZVOUS_EXCEPTION 
  Exception is propagating out of a rendezvous in task %TASK 2 
    %ADA-F-CONSTRAINT_ERRO, CONSTRAINT_ERROR 
    -ADA-I-EXCRAIPRI, Exception raised prior to PC = 00000BA6 
DBG> 

To cancel breakpoints (or tracepoints) set with the /EVENT qualifier, use the CANCEL BREAK/EVENT (or CANCEL TRACE/EVENT) command. Specify the event qualifier and optional task expression in the CANCEL command exactly as you did with the SET command, excluding any WHEN or DO clauses.

You might want to set event breakpoints and tracepoints in a debugger initialization file for your tasking programs. For example:


SET BREAK/EVENT=ACTIVATING 
SET BREAK/EVENT=HANDLED DO (SHOW CALLS) 
SET BREAK/EVENT=ABORT_TERMINATED DO (SHOW CALLS) 
SET BREAK/EVENT=EXCEPTION_TERM DO (SHOW CALLS) 
SET BREAK/EVENT=TERMINATED 

17.7 Additional Task-Debugging Topics

The following sections discuss additional topics related to task debugging:

17.7.1 Debugging Programs with Deadlock Conditions

A deadlock is an error condition in which each task in a group of tasks is suspended and no task in the group can resume execution until some other task in the group executes. Deadlock is a typical error in tasking programs (in much the same way that infinite loops are typical errors in programs that use WHILE statements).

A deadlock is easy to detect: it causes your program to appear to suspend, or hang, in midexecution. When deadlock occurs in a program that is running under debugger control, press Ctrl/C to interrupt the deadlock and display the debugger prompt.

In general, the SHOW TASK/ALL command (see Section 17.4) or the SHOW TASK/STATE=SUSPENDED command is useful because it shows which tasks are suspended in your program and why. The command SET TASK/VISIBLE %NEXT_TASK is particularly useful when debugging in screen mode. It enables you to cycle through all tasks and display the code that each task is executing, including the code in which execution is stopped.

The SHOW TASK/FULL command gives detailed task state information, including information about rendezvous, entry calls, and entry index values. The SET BREAK/EVENT or SET TRACE/EVENT command (see Section 17.6.4) enables you to set breakpoints or tracepoints at or near locations that might lead to deadlock. The SET TASK/PRIORITY and SET TASK/RESTORE commands enable you to see if a low-priority task that never runs is causing the deadlock.

Table 17-9 lists a number of tasking deadlock conditions and suggests debugger commands that are useful in diagnosing the cause.

Table 17-9 Ada Tasking Deadlock Conditions and Debugger Commands for Diagnosing Them
Deadlock Condition Debugger Commands
Self-calling deadlock (a task calls one of its own entries) SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
Circular-calling deadlock (a task calls another task, which calls the first task) SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
Dynamic-calling deadlock (a circular series of entry calls exists, and at least one of the calls is a timed or conditional entry call in a loop) SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
Exception-induced deadlock (an exception prevents a task from answering one of its entry calls, or the propagation of an exception must wait for dependent tasks) SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
SET BREAK/EVENT=DEPENDENTS_EXCEPTION (for Ada programs)
Deadlock because of incorrect run-time calculations for entry indexes, when conditions, and delay statements within select statements SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
EXAMINE
Deadlock due to entries being called in the wrong order SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
Deadlock due to busy-waiting on a variable used as a flag that is to be set by a lower priority task, and the lower priority task never runs because a higher priority task is always ready to execute SHOW TASK/ALL
SHOW TASK/STATE=SUSPENDED
SHOW TASK/FULL
SET TASK/PRIORITY
SET TASK/RESTORE

17.7.2 Automatic Stack Checking in the Debugger

In tasking programs, an undetected stack overflow can occur in certain circumstances and can lead to unpredictable execution. (For more information on task stack overflow, see the DEC Ada or DECthreads documentation.) The debugger automatically does the following stack checks to help you detect the source of stack overflow problems (if the stack pointer is out of bounds, the debugger displays an error message):

The following examples show the kinds of error messages displayed by the debugger when a stack check fails. A warning is issued when most of the stack has been used up, even if the stack has not yet overflowed.


warning: %TASK 2 has used up over 90% of its stack 
  SP: 0011194C  Stack top at: 00111200  Remaining bytes: 1868 
 
error: %TASK 2 has overflowed its stack 
  SP: 0010E93C  Stack top at: 00111200  Remaining bytes: -10436 
 
error: %TASK 2 has underflowed its stack 
  SP: 7FF363A4  Stack base at: 001189FC  Stack top at: 00111200 

One of the unpredictable events that can happen after a stack overflows is that the stack can then underflow. For example, if a task stack overflows and the stack pointer remains in the top guard area, the operating system will attempt to signal an ACCVIO condition. However, because the top guard area is not a writable area of the stack, the operating system cannot write the signal arguments for the ACCVIO. When this happens, the operating system cuts back the stack: it causes the frame pointer and stack pointer to point to the base of the main program stack area, writes the signal arguments, and then modifies the program counter to force an image exit.

If a time-slice AST or other AST occurs at this instant, execution can resume in a different task, and for a while, the program may continue to execute, although not normally (the task whose stack overflowed may use---and overwrite---the main program stack). The debugger stack checks help you to detect this situation. If you step into a task whose stack has been cut back by the operating system, or if you use the SHOW TASK/ALL command at that time, the debugger issues its stack underflow message.

17.7.3 Using Ctrl/Y When Debugging Ada Tasks

Pressing Ctrl/C is the recommended method of interrupting program execution or a debugger command during a debugging session. This returns control to the debugger; pressing Ctrl/Y returns control to DCL level.

If you interrupt a task debugging session by pressing Ctrl/Y, you might have some problems when you then start the debugger at DCL level with the DEBUG command. In such cases, you should insert the following two lines in the source code at the beginning of your main program to name the DEC Ada predefined package CONTROL_C_INTERCEPTION:


with CONTROL_C_INTERCEPTION; 
pragma ELABORATE(CONTROL_C_INTERCEPTION); 

For information on this package, see the DEC Ada documentation.


Part 6
Debugger Command Dictionary

The Debugger Command Dictionary contains detailed reference information about all debugger commands, organized as follows:

1 Debugger Command Format

You can enter debugger commands interactively at the keyboard or store them within a command procedure to be executed later with the execute procedure (@) command.

This section gives the following information:

1.1 General Format

A command string is the complete specification of a debugger command. Although you can continue a command on more than one line, the term command string is used to define an entire command that is passed to the debugger.

A debugger command string consists of a verb and, possibly, parameters and qualifiers.

The verb specifies the command to be executed. Some debugger command strings might consist of only a verb or a verb pair. For example:


DBG> GO
DBG> SHOW IMAGE

A parameter specifies what the verb acts on (for example, a file specification). A qualifier describes or modifies the action taken by the verb. Some command strings might include one or more parameters or qualifiers. In the following examples, COUNT, I, J, and K, OUT2, and PROG4.COM are parameters (@ is the execute procedure command); /SCROLL and /OUTPUT are qualifiers.


DBG> SET WATCH COUNT
DBG> EXAMINE I,J,K
DBG> SELECT/SCROLL/OUTPUT OUT2
DBG> @PROG4.COM

Some commands accept optional WHEN or DO clauses. DO clauses are also used in some screen display definitions.

A WHEN clause consists of the keyword WHEN followed by a conditional expression (within parentheses) that evaluates to true or false in the current language. A DO clause consists of the keyword DO followed by one or more command strings (within parentheses) that are to be executed in the order that they are listed. You must separate multiple command strings with semicolons (;). These points are illustrated in the next example.

The following command string sets a breakpoint on routine SWAP. The breakpoint is triggered whenever the value of J equals 4 during execution. When the breakpoint is triggered, the debugger executes the two commands SHOW CALLS and EXAMINE I,K, in the order indicated.


DBG> SET BREAK SWAP WHEN (J = 4) DO (SHOW CALLS; EXAMINE I,K)

The debugger checks the syntax of the commands in a DO clause when it executes the DO clause. You can nest commands within DO clauses.

1.2 Entering Commands at the Keyboard

When entering a debugger command interactively at the keyboard, you can abbreviate a keyword (verb, qualifier, parameter) to as few characters as are needed to make it unique within the set of all debugger keywords. However, some commonly used commands (for example, EXAMINE, DEPOSIT, GO, STEP) can be abbreviated to their first characters. Also, in some cases, the debugger interprets nonunique abbreviations correctly on the basis of context.

Pressing the Return key terminates the current line, causing the debugger to process it. To continue a long command string on another line, type a hyphen (-) before pressing Return. As a result, the debugger prompt is prefixed with an underscore character (_DBG>), indicating that the command string is still being accepted.

You can enter more than one command string on one line by separating command strings with semicolons (;).

To enter a comment (explanatory text recorded in a debugger log file but otherwise ignored by the debugger), precede the comment text with an exclamation point (!). If the comment wraps to another line, start that line with an exclamation point.

The command line editing functions that are available at the DCL prompt ($) are also available at the debugger prompt (DBG>), including command recall with the up arrow and down arrow keys. For example, pressing the left arrow and right arrow keys moves the cursor one character to the left and right, respectively; pressing Ctrl/H or Ctrl/E moves the cursor to the start or end of the line, respectively; pressing Ctrl/U deletes all the characters to the left of the cursor, and so on.

To interrupt a command that is being processed by the debugger, press Ctrl/C. See the Ctrl/C command.

1.3 Entering Commands in Command Procedures

To maximize legibility, it is best not to abbreviate command keywords in a command procedure. Do not abbreviate command keywords to less than four significant characters (not counting the negation /NO...), to avoid potential conflicts in future releases.

Start a debugger command line at the left margin. (Do not start a command line with a dollar sign ($) as you do when writing a DCL command procedure.)

The beginning of a new line ends the previous command line (the end-of-file character also ends the previous command line). To continue a command string on another line, type a hyphen (-) before starting the new line.

You can enter more than one command string on one line by separating command strings with semicolons (;).

To enter a comment (explanatory text that does not affect the execution of the command procedure), precede the comment text with an exclamation point (!). If the comment wraps to another line, start that line with an exclamation point.


Previous Next Contents Index

[Site home] [Send comments] [Help with this site] [How to order documentation] [OpenVMS site] [Compaq site]
[OpenVMS documentation]

Copyright © Compaq Computer Corporation 1998. All rights reserved.

Legal
4538PRO_038.HTML