Previous | Contents | Index |
When you run your program with the debugger, at least one of the following condition handlers is invoked, in the order given, to handle any exceptions caused by the execution of your program:
A handler can return one of the following three status codes to the Condition Handling Facility:
For more information about condition handling, see the OpenVMS
Programming Concepts Manual.
14.5.3.1 Primary Handler
When you run your program with the debugger, the primary handler is the debugger. Therefore, the debugger has the first opportunity to handle an exception, whether or not the exception is caused by the debugger.
If you enter a SET BREAK/EXCEPTION or SET TRACE/EXCEPTION command, the debugger breaks on (or traces) any exceptions caused by your program. The break (or trace) action occurs before any application-declared handler is invoked.
If you do not enter a SET BREAK/EXCEPTION or SET TRACE/EXCEPTION
command, the primary handler resignals any exceptions caused by your
program.
14.5.3.2 Secondary Handler
The secondary handler is used for special purposes and does not apply
to the types of programs covered in this manual.
14.5.3.3 Call-Frame Handlers (Application-Declared)
Each routine of your program can establish a condition handler, also known as a call-frame handler. The operating system searches for these handlers starting with the routine that is currently executing. If no handler was established for that routine, the system searches for a handler established by the next routine down the call stack, and so on back to the main program, if necessary.
After it is invoked, a handler might perform one of the following actions:
These handlers are controlled by the debugger. They enable the debugger to regain control and display the DBG> prompt if no application-declared handler has handled an exception. Otherwise, the debugging session will terminate and control will pass to the DCL command interpreter.
The final handler is the last frame on the call stack and the first of these two handlers to be invoked. The following example shows what happens when an unhandled exception is propagated from an exception breakpoint to the final handler:
DBG> SET BREAK/EXCEPTION DBG> GO . . . %SYSTEM-F-INTDIV, arithmetic trap, integer divide by zero at PC=0000066C, PSL=03C00022 break on exception preceding TEST\%LINE 13 6: X := 3/Y; DBG> GO %SYSTEM-F-INTDIV, arithmetic trap, integer divide by zero at PC=0000066C, PSL=03C00022 DBG> |
In this example, the first INTDIV message is issued by the primary handler, and the second is issued by the final handler, which then displays the DBG> prompt.
The last-chance handler is invoked only if the final handler cannot gain control because the call stack is corrupted. For example:
DBG> DEPOSIT %FP = 10 DBG> GO . . . %SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual address=0000000A, PC=0000319C, PSL=03C00000 %DEBUG-E-LASTCHANCE, stack exception handlers lost, re-initializing stack DBG> |
The catchall handler, which is part of the operating system, is invoked if the last-chance handler cannot gain control. The catchall handler produces a register dump. This should never occur if the debugger has control of your program, but it can occur if your program encounters an error when running without the debugger.
If, during a debugging session, you observe a register dump and are
returned to DCL level ($), contact your Compaq support representative.
14.5.4 Exception-Related Built-In Symbols
When an exception is signaled, the debugger sets the following exception-related built-in symbols:
Symbol | Description |
---|---|
%EXC_FACILITY | Name of facility that issued the current exception |
%EXC_NAME | Name of current exception |
%ADAEXC_NAME | Ada exception name of current exception (for Ada programs only) |
%EXC_NUMBER | Number of current exception |
%EXC_SEVERITY | Severity code of current exception |
You can use these symbols as follows:
The following examples show the use of some of these symbols. Note that the conditional expressions in the WHEN clauses are language-specific.
DBG> EVALUATE %EXC_NAME 'ACCVIO' DBG> SET TRACE/EXCEPTION WHEN (%EXC_NAME = "ACCVIO") DBG> EVALUATE %EXC_FACILITY 'SYSTEM' DBG> EVALUATE %EXC_NUMBER 12 DBG> EVALUATE/CONDITION_VALUE %EXC_NUMBER %SYSTEM-F-ACCVIO, access violation, reason mask=01, virtual address=FFFFFF30, PC=00007552, PSL=03C00000 DBG> SET BREAK/EXCEPTION WHEN (%EXC_NUMBER = 12) DBG> SET BREAK/EXCEPTION WHEN (%EXC_SEVERITY .NE. "I" .AND. %EXC_SEVERITY .NE. "S") |
Exit handlers are procedures that are called whenever an image requests the $EXIT system service or runs to completion. A user program can declare one or more exit handlers. The debugger always declares its own exit handler.
At program termination, the debugger exit handler executes after all application-declared exit handlers have executed.
To debug an application-declared exit handler:
The SHOW EXIT_HANDLERS command gives a display of the exit handlers that your program has declared. The exit handler routines are displayed in the order that they are called. A routine name is displayed symbolically, if possible. Otherwise, its address is displayed. The debugger's exit handlers are not displayed. For example:
DBG> SHOW EXIT_HANDLERS exit handler at STACKS\CLEANUP exit handler at BLIHANDLER\HANDLER1 DBG> |
A program can use asynchronous system traps (ASTs) either explicitly or
implicitly by calling system services or Run-Time Library (RTL)
routines that call application-defined AST routines. Section 14.7.1
explains how to facilitate debugging by disabling and enabling the
delivery of ASTs originating with your program.
14.7.1 Disabling and Enabling the Delivery of ASTs
Debugging AST-driven programs can be confusing because interrupts originating from the program being debugged can occur, but are not processed, while the debugger is running (processing commands, tracing execution, displaying information, and so on).
By default, the delivery of ASTs is enabled while the program is running. The DISABLE AST command disables the delivery of ASTs while the program is running and causes any such potential interrupts to be queued.
The delivery of ASTs is always disabled when the debugger is running.
If a static watchpoint is in effect, the debugger deactivates the static watchpoint, ASTs, and thread switching, just before a system service call. The debugger reactivates them just after the system service call completes. (For more information, see the SET WATCH command description.)
The ENABLE AST command reenables the delivery of ASTs, including any pending ASTs. The SHOW AST command indicates whether the delivery of ASTs is enabled or disabled.
To control the delivery of ASTs during the execution of a routine
called with the CALL command, use the /[NO]AST qualifiers. The command
CALL/AST enables the delivery of ASTs in the called routine. The
command CALL/NOAST disables the delivery of ASTs in the called routine.
If you do not specify /AST or /NOAST with the CALL command, the
delivery of ASTs is enabled unless you have previously entered the
DISABLE AST command.
14.8 Debugging Translated Images (Alpha and Integrity servers Only)
On OpenVMS Alpha and Integrity server systems, the debugger does not
support attempts to debug translated images. If you must debug a
translated image, use the Delta/XDelta Debugger. For more information
on this debugger, see the OpenVMS Delta/XDelta Debugger Manual.
14.9 Debugging Programs That Perform Synchronization or Communication Functions
Some programs that perform synchronization or communication can pose
problems for debugging. For example, an application being debugged
includes the LCK$M_DEQALL modifier in a $DEQ system service call (this
modifier breaks communication links between the portion of the debugger
in the user process (the kernel) and the debugger main process).
14.10 Debugging Inlined Routines
On OpenVMS systems, the debugger does not support attempts to debug inlined routines. If you attempt to debug an inlined routine, the debugger issues a message that it cannot access the routine, as shown in the following example:
%DEBUG-E-ACCESSR, no read access to address 00000000 |
To work around this problem, compile your program with the /NOOPTIMIZE qualifier.
This chapter describes features of the debugger that are specific to multiprocess programs (programs that run in more than one process). With these features, you can display process information and control the execution of specific processes. You can use these features in addition to those explained in other chapters.
Images discussed in this chapter are debuggable images---that is,
images that can be controlled by debugger. An image that is linked with
the /NOTRACEBACK qualifier cannot be brought under control of the
debugger. As explained in Section 1.2, you get full symbolic
information when debugging an image only for modules that are compiled
and linked with the /DEBUG qualifier.
15.1 Basic Multiprocess Debugging Techniques
This section introduces basic concepts of multiprocess debugging. Refer
to subsequent sections for complete details.
15.1.1 Starting a Multiprocess Debugging Session
This section explains the easiest way to start a multiprocess debugging session. Section 15.16.3 describes additional ways to start the debugger.
To start a multiprocess debugging session, start the kept debugger. For example,
$ debug/keep OpenVMS Integrity server Debug64 Version T8.2-008 DBG> |
In a multiprocess debugging session, the debugger traces each new process that is brought under control. The debugger identifies each process with a decimal process number, as shown in Example 15-1.
Example 15-1 RUN/NEW Command |
---|
DBG> SHOW PROCESS Number Name State Current PC * 1 DBGK$$2727282C activated SERVER\__main DBG> RUN/NEW CLIENT process 2 %DEBUG-I-INITIAL, Language: C, Module: CLIENT %DEBUG-I-NOTATMAIN, Type GO to reach MAIN program predefined trace on activation at CLIENT\__main all> SHOW PROCESS Number Name State Current PC * 1 DBGK$$2727282C activated SERVER\__main 2 USER_2 activated CLIENT\__main all> |
The RUN/NEW CLIENT command in Example 15-1 starts the program CLIENT in a new process. The first time (in a debugging session) that the debugger has more than one process under its control, it changes its prompt to all> to identify the set of all processes under its control.
Once the debugger is aware of more than one process, the debugger prompt changes to the identifier of the current process set, followed by a right angle bracket (>).
Conceptually, each process belongs to a set of one, identified by default by the unique decimal number assigned to it when the debugger takes control of the process. A process can belong to more than one set. All processes under debugger control are grouped by default into a set named all.
You can group processes into user-named sets with the DEFINE /PROCESS_SET command.
Debugger commands apply by default to the current process set. By default, the current process set is the set named all. You can change the current process set with the SET PROCESS command.
The set of processes at which a command is directed is called the command process set. The default command process set is the current process set.
You can give a debugger command that applies to a command process set other than the current process set without changing the current process set. To do so, prefix the command with the name of the process set followed by a right angle bracket (>). For example:
all> 1,2,5> GO |
1,2,5> is a process set prefix. This syntax allows you to cut and paste commands from a previous command line.
The visible process is the process that is shown in current displays, and is identified by an asterisk (*) in column 1 in a SHOW PROCESS display. You can change the visible process with the SET PROCESS/VISIBLE command. For example:
all> SHOW PROCESS Number Name State Current PC * 1 DBGK$$2727282C activated SERVER\__main 2 USER_2 activated CLIENT\__main all> |
In the above example, process number 1 is the visible process.
15.2 Obtaining Information About Processes
Use the SHOW PROCESS command to obtain information about processes that are currently under control of your debugging session. By default, SHOW PROCESS displays information about all processes under control of the debugger. (These are the processes in process set all.) Example 15-2 shows the type of information displayed immediately after you start the debugger.
Example 15-2 SHOW PROCESS Command |
---|
DBG> SHOW PROCESS/BRIEF/ALL Number Name State Current PC * 1 JONES activated MAIN_PROG\%LINE 2 DBG> |
Note that the qualifiers /BRIEF and /ALL are the default. Note also that the debugger displays its default prompt, because the debugger still has only one process under its control. The SHOW PROCESS command provides the following information about each process specified:
State | Description | |
---|---|---|
Running | Executing under control of the debugger. | |
Stopped | ||
Activated | The image and its process have just been brought under debugger control. | |
Break 1 | A breakpoint was triggered. | |
Interrupted |
Execution was interrupted in that process, in one of the following ways:
|
|
Step 1 | A STEP command has completed. | |
Trace 1 | A tracepoint was triggered. | |
Unhandled exception | An unhandled exception was encountered. | |
Watch of | A watchpoint was triggered. | |
Terminated | The image has terminated execution but the process is still under debugger control. Therefore, you can obtain information about the image and its process. |
Returning to Example 15-2, if you now enter a STEP command followed by a SHOW PROCESS command, the state column in the SHOW PROCESS display indicates that execution is paused at the completion of a step. For example:
DBG> STEP DBG> SHOW PROCESS Number Name State Current PC * 1 JONES step MAIN_PROG\%LINE 3 DBG> |
Similarly, if you were to set a breakpoint and then enter a GO command,
a SHOW PROCESS command entered once the breakpoint has triggered
identifies the state as break.
15.3 Process Specification
Each new process to which the debugger connects is identified by a process-number. The first process is process-number 1, the second process is process-number 2, and so on. When a process stops, its process number is recycled and is available to the debugger for assignment to a subsequent process.
Processes are referred to using the process-spec. The most simple process-spec is either a process-name created by OpenVMS when the process is created, or a process-number created by the debugger when the debugger gains control of the process. A process-spec that consists of only numbers is interpreted as a process number. Within debugger commands, you can use process-numbers to specify individual processes (for example, "2,3,4,5").
A process-spec-item can be a name, in which case it can refer to a process-name or a process-set-name. The debugger tries first to find a process-set with that name. If unsuccessful, the debugger then tries to match a process to the name. You can explicitly specify the process-name by using the %PROCESS_NAME lexical function.
Example 15-3 contains the complete process specification syntax.
Example 15-3 Process Specification Syntax |
---|
process-spec ::= process-spec-item [, process-spec-item] process-spec-item ::= named-item | numbered-item | pid-item | process-set-name | special-item named-item ::= [%PROCESS_NAME] wildcard-name numbered-item ::= numbered-process numbered-process ::= [%PROCESS_NUMBER] decimal-number pid-item ::= %PROCESS_ID VMS-process-identifier process-set-name ::= name special-item ::= %NEXT_PROCESS | %PREVIOUS_PROCESS | %VISIBLE_PROCESS |
Previous | Next | Contents | Index |