OpenVMS Debugger Manual
Chapter 10 Using the Debugger
This chapter explains how to:
The chapter describes window actions and window menu choices, but you
can perform most common debugger operations by choosing items from
context-sensitive pop-up menus. To access these menus, click MB3 while
the mouse pointer is in the window area.
You can also enter commands at the HP DECwindows Motif for OpenVMS command prompt. For
information about entering debugger commands, see Section 8.3.
For the source code of programs EIGHTQUEENS.EXE and 8QUEENS.EXE, shown
in the figures of this chapter, see Appendix D.
10.1 Displaying the Source Code of Your Program
The debugger displays the source code of your program in the main
window (see Figure 10-1).
Figure 10-1 Source Display
Whenever execution is suspended (for example, at a breakpoint), the
debugger updates the source display by displaying the code surrounding
the point at which execution is paused. The current-location pointer,
to the left of the source code, marks which line of code will execute
next. (A source line corresponds to one or more programming-language
statements, depending on the language and coding style.)
By default, the debugger displays compiler-generated line numbers to
the left of the source code. These numbers help identify breakpoints,
which are listed in the breakpoint view (see Section 10.4.4). You can
choose not to display line numbers so that more of the source code can
show in the window. To hide or display line numbers, toggle Display
Line Numbers from the File menu on the main window.
The Call Stack menu, between the source view and the push button view,
shows the name of the routine whose source code is displayed.
The current-location pointer is normally filled in as shown in
Figure 10-1. It is cleared if the displayed code is not that of the
routine in which execution is paused (see Section 10.1.3 and
Section 10.6.2).
You can use the scroll bars to show more of the source code. However,
you can scroll vertically through only one module of
your program at a time. (A module corresponds generally to a
compilation unit. With many programming languages, a module corresponds
to the contents of a source file. With some languages, such as Ada, a
source file might contain one or more modules.)
The following sections explain how to display source code for other
parts of your program so that you can set breakpoints in various
modules, and so on. Section 10.1.3 explains what to do if the debugger
cannot find source code for display. Section 10.6.2 explains how to
display the source code associated with routines that are currently
active on the call stack.
After navigating the main window, you can redisplay the location at
which execution is paused by clicking on the Call Stack menu.
If your program was optimized during compilation, the source code
displayed might not reflect the actual contents of some program
locations
(see Section 1.2).
10.1.1 Displaying the Source Code of Another Routine
To display source code of another routine:
- Choose Browse Sources from the File menu on the main window (see
Figure 10-2).
Select SYMBOLIC display the names of all modules
linked in the image. Select ALL to display the names of only those
modules for which the debugger has symbolic information. The Source
Browser dialog box displays the name of your executable image, which is
highlighted, and the class of shareable images linked with it (SYMBOLIC
or ALL). The name of a linked image is dimmed if no symbolic
information is available for that image.
- Double click on the name of your executable image. The names of
the modules in that image are displayed (indented) under the image name.
- Double click on the name of the module containing the routine of
interest. The names of the routines in that module are displayed
(indented) under the module name, and the Display Source button is now
highlighted.
- Click on the name of the routine whose source code you want to
display.
- Click on the Display Source push button. The debugger displays in
the source view the source code of the target routine, along with an
empty breakpoint button to the left of the source code. If the
instruction view is open, this display is updated to show the machine
code of the target routine.
Section 10.6.2 describes an alternative way to display routine source
code for routines currently active on the call stack.
Figure 10-2 Displaying Source Code of Another Routine
10.1.2 Displaying the Source Code of Another Module
To display source code of another module:
- Choose Browse Sources from the File menu on the main window.
Select SYMBOLIC display the names of all modules linked in the
image. Select ALL to display the names of only those modules for which
the debugger has symbolic information. The Source Browser dialog
box displays the name of your executable image, which is highlighted,
and the class of shareable images linked with it (SYMBOLIC or ALL). The
names of the shareable images are dimmed if no symbolic information is
available for them.
- Double click on the name of your executable image. The names of
the modules in that image are displayed (indented) under the image name.
- Click on the name of the module whose source code you want to
display. The Display Source button is now highlighted.
- Click on Display Source. The source display in the main window now
shows the routine's source code. (If the instruction display in the
instruction view is open, this display is updated to show the routine's
instruction code.)
10.1.3 Making Source Code Available for Display
In certain cases, the debugger cannot display source code. Possible
causes are:
- Execution might be paused within a module of your program that was
compiled or linked without the debug option (see Section 1.2).
- Execution might be paused within a system or library routine for
which no symbolic information is intended to be available. In such
cases you can quickly return execution to the calling routine by
clicking one or more times on the S/ret button in the push button view
(see Section 10.3.5).
- The source file might have been moved to a different directory
after it was compiled. Section 10.1.4 explains how to tell the debugger
where to look for source files.
If the debugger cannot find source code for display, it tries to
display the source code for the next routine down on the call stack for
which source code is available. If the debugger can display source code
for such a routine, the current-location pointer is moved to point to
the source line to which execution returns in the calling routine.
10.1.4 Specifying the Location of Source Files
Information about the characteristics and the location of source files
is embedded in the debug symbol table of your program. If a source file
has been moved to a different directory since compile time, the
debugger might not find the file. To direct the debugger to your source
files, use the SET SOURCE command at the DBG> prompt (see
Section 6.2).
10.2 Editing Your Program
The debugger provides a simple text editor you can use to edit your
source files while debugging your program (see Figure 10-3).
The text editor available through the debugger's HP DECwindows Motif for OpenVMS menu
interface is a simple convenience feature, not intended to replace
sophisticated text editors such as the Language-Sensitive Editor (LSE).
You cannot substitute a more sophisticated editor for the text editor
invoked with the Edit File item in the Commands menu. To use a
different editor, enter the EDIT command at the DBG> prompt in the
command view (see EDIT in the Command Reference Dictionary of
this manual).
Note
When you enter an EDIT command at the command prompt, the debugger uses
the DECterm window that invoked the debugging session as the
user-defined-editor window (as opposed to the debugger's built-in
editor, which is hardwired to the COMMANDS EDIT FILE pull-down menu).
This behavior constitutes a tradeoff that allows a more flexible choice
of editors. If you inadvertently exit this DECterm window using FILE
EXIT or MWM Close, the debugging session terminates abruptly, having
lost its parent window.
|
Figure 10-3 Editor Window
To invoke the editor, choose the Edit File item in the Commands menu on
the main window. By default, the editor opens a buffer and displays the
module currently displayed in the source view. The buffer is named with
the file specification of the file in the buffer. If no file is
displayed in the source view, the editor displays an empty text buffer,
called main_buffer. The buffer name appears in the buffer menu, which
is just under the menu bar of the editor view.
The editor allows you to create any number of text buffers by choosing
New (for empty text buffers) or Open (for existing files) from the File
menu. The name of each text buffer appears in the buffer menu. You can
cut, copy, and paste text from buffer to buffer by choosing items from
the Edit menu and selecting buffers from the buffer menu.
You can perform forward and backward search and replace operations by
entering strings in the Find and Replace with fields and clicking on a
directional arrow. You can perform a repeated search for the string by
continuing to press the Return key. You can also continue a search by
choosing the Find/Replace Next or Find/Replace Previous items in the
Edit menu.
To save the file, choose the Save or Save As... items from the File
menu. If you do not save your corrections before closing a modified
buffer or exiting the debugger, the debugger displays a warning message.
To test any changes to the source code:
- Select a DECterm window separate from that in which the debugger is
running.
- Recompile the program.
- Relink the program.
- Return to the debugging session.
- Choose the Run Image... item in the File menu on the main window.
10.3 Executing Your Program
This section explains how to:
- Determine where execution is currently paused within your program
- Start or resume program execution
- Execute the program one source line at a time, step by step
For information about rerunning your program or running another program
from the current debugging session, see Section 9.3 and Section 9.4.
10.3.1 Determining Where Execution Is Currently Paused
To determine where execution is currently paused within your program:
- If the current-location pointer is not visible in the main window,
click on the Call Stack menu of that window to display the pointer (see
Figure 10-1).
- Look at the current-location pointer:
- If the pointer is filled in, it marks the source line whose code
will execute next (see Section 10.1). The Call Stack menu always shows
the routine at scope level 0 (where execution is paused) when the
pointer is filled in.
- If the pointer is cleared, the source code displayed is that of a
calling routine, and the pointer marks the source line to which
execution returns in that routine:
- If the Call Stack menu shows level 0, source code is not available
for display for the routine in which execution is paused (see
Section 10.1.3).
- If the Call Stack menu shows a level other than 0, you are
displaying the source code for a calling routine (see Section 10.6.2).
To list the sequence of routine calls that are currently active on the
call stack, click on the Call Stack menu. Level 0 denotes the routine
in which execution is paused, level 1 denotes the calling routine, and
so on.
10.3.2 Starting or Resuming Program Execution
To start program execution or resume execution from the current
location, click on the Go button in the push button view (see
Figure 8-3).
Letting your program run freely without debugger intervention is useful
in situations such as the following:
- To test for an infinite loop. In this case, you start execution;
then, if your program does not terminate and you suspect that it is
looping, click on the Stop button. The main window will show where you
interrupted program execution, and the Call Stack menu will identify
the sequence of routine calls at that point (see Section 10.3.1).
- To execute your program directly to a particular location. In this
case, you first set a breakpoint at the location (see Section 10.4)
and then start execution.
Once started, program execution continues until one of the following
events occurs:
- The program completes execution.
- A breakpoint is reached (including a conditional breakpoint whose
condition is true).
- A watchpoint is triggered.
- An exception is signaled.
- You click on the Stop button on the push button view.
Whenever the debugger suspends execution of the program, the main
window display is updated and the current-location pointer marks which
line of code will execute next.
10.3.3 Executing Your Program One Source Line at a Time
To execute one source line of your program, click on the
STEP button in the push button view or enter the STEP command in the
command view. This debugging technique (called
stepping) is one of the most commonly used.
After the line executes, the source view is updated and the
current-location pointer marks which line of code will execute next.
Note the following points about source lines and the stepping behavior:
- A source line can consist of one or more programming language
elements depending on the language and coding style used.
- When you click on the STEP button, the debugger executes one
executable line and suspends execution at the start of the next
executable line, skipping over any intervening nonexecutable lines.
- Executable lines are those for which instructions were generated
by the compiler (for example, lines with routine call or assignment
statements). Executable lines have a button to their left in the main
window.
- Examples of nonexecutable lines are comment lines or lines with
variable declarations without value assignments. Nonexecutable lines do
not have a button to their left in the main window.
Keep in mind that if you optimized your code at compilation time, the
source code displayed might not reflect the code that is actually
executing (see Section 1.2).
10.3.4 Stepping into a Called Routine
When program execution is paused at a routine call statement, clicking
on the STEP button typically executes the called routine in one step
(depending on the coding style used), and the debugger suspends
execution at the next source line in the calling routine (assuming no
breakpoint was set within the called routine). This enables you to step
through the code quickly without having to trace execution through any
called routines (some of which might be system or library routines).
This is called stepping over called routines.
To step into a called routine so that you can execute it one line at a
time:
- Suspend execution at the routine call statement, for example, by
setting a breakpoint (see Section 10.4) and then clicking on the Go
button in the push button view.
- When execution is paused at the call statement, click on the
S/in button in the push button view, or enter the STEP/INTO command at
the DBG> prompt. This moves execution just past the start of the
called routine.
Once execution is within the called routine, click on the STEP button
to execute the routine line by line.
Clicking on the S/in button when execution is not paused at a routine
call statement is the same as clicking on the STEP button.
10.3.5 Returning from a Called Routine
When execution is suspended within a called routine, you can execute
your program directly to the end of that routine by clicking on the
S/ret button in the push button view, or enter the STEP/RETURN command
at the DBG> prompt.
The debugger suspends execution just before the routine's return
instruction executes. At that point, the routine's call frame has not
been deleted from the call stack, so you can still get the values of
variables local to that routine, and so on.
You can also use the S/call button in the push button view (or enter
the STEP/CALL command at the DBG> prompt) to execute the program
directly to the next Return or Call instruction.
The S/ret button is particularly useful if you have inadvertently
stepped into a system or library routine (see Section 10.1.3).
10.4 Suspending Execution by Setting Breakpoints
A breakpoint is a location in your program at which you want execution
to stop so that you can check the current value of a variable, step
into a routine, and so on.
When using the debugger's HP DECwindows Motif for OpenVMS user interface, you can set
breakpoints on:
- Specific source lines
- Specific routines (functions, subprograms, and so on)
- Exceptions signaled during the execution of your program
Note
If you are stopped at a breakpoint in a routine that has control of the
mouse pointer by a PointerGrab or a KeyboardGrab, your workstation will
hang.
To work around this problem, debug your program using two workstations.
For more information, see Section 9.8.3.1.
|
The debugger provides two ways to qualify breakpoints:
- You can set a conditional breakpoint. The
debugger suspends execution at a conditional breakpoint only when a
specified relational expression is evaluated as true.
- You can set an action breakpoint. The debugger
executes one or more specified system-specific commands when it reaches
the breakpoint.
You can set a breakpoint that is both a conditional and action
breakpoint.
The following sections explain these breakpoint options.
10.4.1 Setting Breakpoints on Source Lines
You can set a breakpoint on any source line that has a button to its
left in the source display. These are the lines for which the compiler
has generated executable code (routine declarations, assignment
statements, and so on).
To set a breakpoint on a source line:
- Find the source line on which you want to set a breakpoint (see
Section 10.1).
- Click on the button to the left of that line. (The breakpoint is
set when the button is filled in.) The breakpoint is set at the start
of the source line---that is, on the first machine-code instruction
associated with that line.
Figure 10-4 shows that a breakpoint has been set on the start of line
37.
Figure 10-4 Setting a Breakpoint on a Source Line
10.4.2 Setting Breakpoints on Routines with Source Browser
Setting a breakpoint on a routine enables you to move execution
directly to the routine and inspect the local environment.
To set a breakpoint on a routine:
- Choose Browse Sources from the File menu on the main window (see
Figure 10-2).
Select SYMBOLIC to display the names of all modules
linked in the image. Select ALL to display the names of only those
modules for which the debugger has symbolic information. The Source
Browser dialog box displays the name of your executable image, which is
highlighted, and the class of shareable images linked with it (SYMBOLIC
or ALL). The name of a linked image is dimmed if no symbolic
information is available for that image.
- Double click on the name of the executable image. The names of the
modules in that image are displayed (indented) under the image name.
- Double click on the name of the target module. The names of the
routines in that module are displayed (indented) under the module name
(see Figure 10-5).
- Double click on the name of the routine on which to set a
breakpoint. The debugger echoes the results of your SET BREAKPOINT
command on the command line in the command view.
Alternatively, click once on the name of the routine, then click
the Set Breakpoint button in the Source Browser view. The debugger
echoes the results of your SET BREAKPOINT command on the command line
in the command view.
Figure 10-5 Setting a Breakpoint on a Routine
10.4.3 Setting an Exception Breakpoint
An exception breakpoint suspends execution when an
exception is signaled and before any exception handler declared by your
program executes. This enables you to step into the exception handler
(if one is available) to check the flow of control.
To set an exception breakpoint, choose On Exception from the Break menu
on the main window or the optional views window.
10.4.4 Identifying the Currently Set Breakpoints
There are three ways to determine which breakpoints are currently set:
- Scroll through your source code and note the lines whose
breakpoint button is filled in. This method can be time consuming and
also does not show which breakpoints were set and then deactivated (see
Section 10.4.5).
- Choose Views... from the Options menu on the main window or the
optional views window. When the Views dialog box appears, click on
Breakpoint View to display the breakpoint view (see Figure 8-4).
The breakpoint view lists a module name and line number for each
breakpoint (see Section 10.1). A filled-in button next to the
breakpoint identification indicates that the breakpoint is activated. A
cleared button indicates that the breakpoint is deactivated.
- Enter the SHOW BREAK command at the DBG> prompt in the command
view. The debugger lists all the breakpoints that are currently set,
including specifications for conditional breakpoints, and commands to
be executed at action breakpoints.
|