Using Sun WorkShop

Chapter 5 Debugging a Program

Sun WorkShop provides an integrated debugging service that can run a program in a controlled fashion and inspect the state of a stopped program. Sun WorkShop gives you complete control of the dynamic execution of a program, including the collection of performance data.

You can determine where a program crashed, view the values of variables and expressions, set breakpoints in the code, and run and trace a program. In addition, machine-level and other commands are available to help you debug code. You can use standard dbx commands in the Dbx Commands window.

This chapter is organized into the following sections:

Debugging Features

When debugging in Sun WorkShop, you have access to an extensive range of event management, process control, and data inspection features that allow you to:

Preparing a Program for Debugging

To prepare an application for debugging, compile the application using the -g or -g0 (zero) option, which instructs the compiler to generate debugging information during compilation. For information on how to specify these options in your makefile, see Appendix B, The make Utility and Makefiles" For more detailed information on preparing your program for debugging, see Debugging a Program With dbx.

Starting Debugging

You can debug the current program, a program previously run or debugged in Sun WorkShop, or a program that is new to Sun WorkShop (not part of your picklist).

The current program name appears in the Debugging window header. If you just built a target, a program with the same name as the target (if it exists in the current directory) is the current program.

To start debugging a program:

  1. Select a debugging state.

    Choose Debug > Quick Mode to run a program normally, with the option of switching to debugging at any point. For more information on Quick Mode, see "Quick Mode".

    Choose Debug > Debug Mode or click the Debug button in the Sun WorkShop main window to debug the program using the full functionality of the debugger.

  2. Select the program to debug.

    To start debugging the current program, click the Debug button in the Sun WorkShop main window.

    To start debugging a program other than the current program, do one of the following:

    • To debug a program previously run or debugged in Sun WorkShop, select the program from the picklist in the Sun WorkShop main window or the Debugging window.

    • To debug a program that is not on your picklist, load the new program by choosing Debug > New Program.

    • To attach to another running process, choose Debug > Attach Process.

    • To debug a core dump file from an unsuccessful program execution, choose Debug > Load Core File.

    Your program is loaded and the primary Sun WorkShop debugging windows are displayed (see "Sun WorkShop Debugging Windows"").

  3. Run your program by clicking on the Start or Go button, or choosing Execute > Start or Execute > Go in the Debugging window.


    Note -

    Before you begin debugging, you can change run parameters such as arguments, the run directory, or environment variables (see "Changing Run Parameters").


Sun WorkShop Debugging Windows

Sun WorkShop simplifies the debugging task by providing you with an intuitive, easy-to-use interface. When you start debugging, the Debugging window and a text editor window (see "Editor Window") are displayed. If you have created custom buttons (see "Using the Button Editor"), the Custom Buttons window is also displayed.

Debugging Window

You perform most debugging operations from the Debugging window, shown in Figure 5-1, and the windows you can access from it.

Figure 5-1 Sun WorkShop Debugging Window

Graphic

Debug menu 

Provides commands to debug a program, process, or core file; customize options; and manage sessions. 

Execute menu 

Provides commands to run or single-step through lines of code. 

Data menu 

Provides commands to evaluate the selection in the Debugging window. 

Threads menu 

Provides commands to hide and expose threads in the Threads/Sessions pane. 

Stack menu 

Provides commands to move up, down, and pop the stack. 

Checks menu 

Provides commands to enable and use runtime checking. 

Windows menu 

Provides commands to open the Breakpoints, Data Display, and other debugging windows. 

Help menu 

Provides commands to display online help. 

Start button 

Runs the program from the beginning. 

Up button 

Moves up the call stack one function. 

Down button 

Moves down the call stack one function. 

Go button 

Runs the program from the current location. 

Interrupt button 

Interrupts the program; equivalent to the dbx command Ctrl+C.

Step Into button 

Single-steps into a function. 

Step Over button 

Single-steps over the current function. 

Step Out button 

Steps past the end of the current function. 

Fix button 

Recompiles all changed files and continue debugging. 

Debug Status area 

Displays information about the state of your program. 

Data History pane 

Displays history when evaluating expressions, querying for type, and modifying values. 

Threads/Sessions pane 

If the Threads radio button is selected, lists information about the threads in a multithreaded program. If the Sessions radio button is selected, lists current debugging sessions.  

Stack pane 

Shows you the current state of the call stack and lets you move to different stack frames. 

Dbx Commands window 

Lets you enter and view the output of dbx commands (displayed only if Show Dbx Commands Window in a separate window is set to No in the Window Layout Category in the Debugging Options dialog box).

Message area 

Displays messages about operations in the window. 

Editor Window

The integration of Sun WorkShop with three text editors (vi, GNU Emacs, and XEmacs) allows you to edit a program's source code while using full debugging functionality.

You can perform basic debugging operations from a text editor window displaying the source code. Figure 5-2 shows the XEmacs editor window displaying source code during debugging. In the editor window, you can view and modify source code. When you start a debugging session, Sun WorkShop automatically displays the programs's main routine in an editor window. You can change the colors used to highlight lines in the source code displayed in the editor window (current function, breakpoint, and so on) by editing the WORKSHOP resource file (see "Highlight Colors in Editor Windows").

The editor window tool bar provides access to common debugging operations, especially those that use a source component as an argument, plus buttons from other parts of Sun WorkShop.

For information on choosing the editor for a Sun WorkShop session, see "Selecting and Using Text Editors".

Figure 5-2 Emacs Editor Window Displaying Source Code

Graphic

Custom Buttons Window

The Custom Buttons window contains custom buttons you create using the Button Editor or the dbx command button. If you have created custom buttons, the window opens automatically when you start Sun WorkShop.

If you used a previous version of the debugger and your .dbxrc file includes commands to create custom buttons, these buttons automatically appear in the Custom Buttons window.

You can resize the Custom Buttons window and position the window wherever you want, but you must close it separately.

Using the Button Editor

You can use the Button Editor (see Figure 5-3) to add, remove, or edit buttons in the Custom Buttons window. Buttons you add to the Custom Buttons window are stored in your Sun WorkShop options file. You no longer need to store buttons in your .dbxrc file. You cannot add buttons to, or remove buttons from, your .dbxrc file with the Button Editor.

Figure 5-3 Button Editor Window

Graphic

To open the Button Editor, choose Windows > Button Editor in the Debugging window.

You can add buttons from the button list to the Custom Buttons window. If you want to add a button that is not on the button list, you must first import the button, if it already exists (see "Adding Builtin Buttons to the Button Editor""), or create the button using the Create/Edit Button panel in the Button Editor (see "Adding a Button to the Button Editor"").

Adding Builtin Buttons to the Button Editor

To import buttons to the Button Editor:

  1. Click Builtin Buttons to display the Button Palette.

    The builtin button list in the Button Palette lists:

    • All the buttons that populate the tool bars in the Debugger window

    • A number of buttons that access functionality available only from the menus (such as the Breakpoints button to open the Breakpoints window)

    • Some buttons that offer functionality not available on the tool bar or the menus (such as the Dump button to print local variables)

  2. Select the buttons you want to import to the Button Editor and click OK.

    The buttons are added to the button list in the Button Editor.

Adding a Button to the Button Editor

To add a button to the Button Editor:

  1. Decide whether you want to put text or an icon on the button.

  2. To put text on the button, click the Text radio button and type the text in the corresponding text box.

  3. To put an icon on the button, click the Icon radio button, and type the file name of an icon.

    Click the browse button to display a dialog box you can use to choose an icon file. The icon file must be in the .xpm file format. Sun WorkShop tool bar icons are 20x20 pixels, and use only colors from the Sun WorkShop palette.


    Tip -

    You can use the CDE application dticon to create an .xpm file. Most graphics programs can also save files in .xpm format.


  4. In the Dbx Command text box, type the dbx command you want executed when the button is clicked.


    Tip -

    Type commands in the Dbx Commands window to see what commands are available.


  5. If you want the button to execute a dbx command that takes an argument, you must select one of the radio buttons under Append/Insert(%s) To Command On Button Press to specify the text to append to the command.

    • The Nothing radio button is selected by default indicating that no text is to be added to the command.

    • If you click the Selected Text radio button, the current Sun WorkShop selection is appended to the command.

    • If you click the File: Line Number radio button, the file name and line number of the selection are appended to the command.

  6. If you want the argument embedded in the command rather than appended to it, type %s in the command string to indicate the position of the argument.

    For example, if you type the following command string in the Dbx Command text box

    stop at %s -temp

    and select the File: Line Number of Selection radio button, the button will execute the following command if it is clicked when line 25 in main.cc is selected:

    stop at "main.cc":25 -temp


    Note -

    The command string should contain only one %s, and it cannot contain an escape sequence. For example, stop %%s -temp produces stop %"main.cc":25.


  7. Click Add and the button is added to the button list.

Adding the Buttons to the Custom Buttons Window

You can add the buttons in the button list in the Button Editor to the Custom Buttons window.

To add a button to the Custom Buttons window, click Apply to add the new button to the Custom Buttons window.


  1. Note -

    You can also add a button to the Custom Buttons window using the dbx button command.


Editing an Existing Button

To edit an existing button in the Button Editor:

  1. Select the button in the button list.

  2. Edit its properties using the text boxes and radio buttons in the Create/Edit Button panel, as described in "Adding a Button to the Button Editor".

  3. Click Change to apply the new properties to the button.

  4. Click Apply to replace the button in the Custom Buttons window with the edited button.

Rearranging Buttons

You can change the position of a button in the Custom Buttons window by moving it up or down on the button list in the Button Editor.

To rearrange the buttons:

  1. In the button list, select the button you want to move.

  2. Click Move Up or Move Down until the button's position in the button list corresponds to where you want it to be displayed in the Custom Buttons window.

  3. Click Apply and the button is displayed in its new position in the Custom buttons window.

Removing a Button

You can remove a button from the Custom Buttons window by deleting it from the button list in the Button Editor.

To remove a button:

  1. In the button list, select the button you want to delete.

  2. Click Delete and the button is deleted from the button list.

  3. To remove the button from the Custom Buttons window, click Apply.


    Note -

    You can also remove a button from the Custom Buttons window using the dbx unbutton command.



    Note -

    You cannot permanently delete a button stored in your .dbxrc file using the Button Editor. The button will reappear in your next debugging session. You can remove such a button by editing your .dbxrc file.


Basic Debugging Steps

The following sections describe the basic steps to perform after you start debugging a program. For more detailed information on any of the steps, see Debugging a Program With dbx.

Changing Run Parameters

You can change run parameters such as arguments, the run directory, and environment variables during a debugging session.

Specifying Program Arguments

You can specify program arguments when you load your program for debugging, and edit them at any time once your program is loaded.

When you enter arguments in the text box that contain characters that have special meaning to the shell, make sure you set them off with either a backslash (\) or quotes (" "). The special characters are | & ; < > ( ) $ ` \ " ' * ? [ ] Space Tab Newline.

To specify program arguments when loading a program, type the arguments in the Arguments text box of the Debug New Program dialog box as if you were typing them on the command line. Do not include the program name.

To edit program arguments once a program is loaded:

  1. Choose Debug > Edit Run Parameters to open the Edit Run Parameters dialog box.

  2. Add or change arguments in the Arguments text box.

  3. Click OK.

Specifying a Run Directory

You can specify a run directory when loading your program for debugging and change the run directory at any time once a program is loaded. When your program is loaded, the directory you selected as the run directory is made the current working directory of the debugger.

To specify a run directory when loading a program:

  1. Type the directory name in the Run Directory text box or click the browse button to display the Run Directory dialog box, in which you can select the directory name.

  2. Click OK.

To change the run directory once a program is loaded:

  1. Choose Debug > Edit Run Parameters to open the Edit Run Parameters dialog box.

  2. Type the directory name in the Run Directory text box or click the browse button to display the Run Directory dialog box, in which you can select the directory name.

  3. Click OK.

Setting Environment Variables

You can specify the environment variables that are in effect when the program runs. When you run the program, setenv commands for these environment variables are prepended to the run command.

Using the Environment Variables dialog box, you can add or delete environment variables to the Persistent Environment Variables list. All environment variables in the Persistent Environment Variables list are saved with your WorkSet.


Note -

The Persistent Environment Variables list for running your program is not the same as the Persistent Environment Variables list for building your program described in "Using Environment Variables".


To open the Environment Variables dialog box:

Adding An Environment Variable

To add an environment variable to the Persistent Environment Variables list:

  1. Type the name of an environment variable in the Name text box.

  2. Type a value for the variable in the Value text box.

    If you make a mistake, click Clear to remove entries in the Name and Value text boxes.

  3. Click Add to add the environment variable to the Persistent Environment Variables list.

  4. Repeat the previous three steps to add other environment variables.

  5. Click OK to close the dialog box.


    Note -

    Pressing the Return key after each step move the input focus to the next step.


Deleting an Environment Variable

To delete a variable from the Persistent Environment Variables list:

  1. Select a variable from the list.

  2. Click Delete (Delete All removes all environment variables in the list).

  3. Click OK to establish the change and close the dialog box.

Changing the Value of an Environment Variable

To change the value of an environment variable in the Persistent Environment Variables list:

  1. Select an environment variable in the list.

  2. Type a new value in the Value text box and click Change.

  3. Click OK to establish the change and close the dialog box.

Reviewing and Overriding Environment Variables

An environment variable definition that appears in the Persistent Environment Variables list overrides any environment variable with the same name that appears in the current debugging environment.

To review the current debugging environment variable definitions, click More to open the Current Environment list, which includes all the environment variables in the debugging environment for your program. You can filter the list using the Filter text box.

To override the value of an environment variable:

  1. Select an environment variable in the Current Environment list.

  2. Click <<Add to add the environment variable to the Persistent Environment Variables list.

  3. Type a new value in the Value text box and click Change.

  4. Click OK to establish the change and close the dialog box.

    The environment variable definition in the Persistent Environment Variables list overrides the environment variable definition in the current debugging environment, and is saved with your WorkSet.


Note -

To delete a variable and unset its value, you can use the dbx command unset variable.


Stepping Through Your Code

You can view your code by stepping--that is, moving through your code one line at a time. As you step, a green highlighted line known as the program counter marks your place in the program. With each step, the program counter moves to the source line which is next to be executed, always showing you the next line to be executed.

There are three ways to step:

Step Into 

Proceed forward one source line; if the source line is a function call, the debugger stops before the first statement of the function. 

Step Over 

Proceed forward one source line; if the source line is a function call, the debugger executes the entire function without stepping through the individual function instructions. 

Step Out 

Finish execution of the present function and stop on the source line immediately following the call to that function. 


Note -

Sometimes after the current function finishes executing, the highlight returns to the line of the call. In such cases, some extra post-call instructions remain to be executed. Stepping into or over again does not call the function again.


To view your code by stepping:

  1. Wait until your program stops, or interrupt execution by choosing Execute > Interrupt, clicking the Interrupt button, or pressing Ctrl+Break.

  2. In the editor window, step through your code one line at a time, moving through functions, around functions, or out of functions:

    • To step forward in your program one source line, choose Execute > Step Into or click the Step Into button (see Figure 5-1 or Figure 5-2) or press F8.

    • To step forward one source line in the current function, choose Execute > Step Over or click the Step Over button or press F7.

    • To finish executing the current function and stop execution on the source line immediately following the call to the function, choose Execute > Step Out or click the Step Out button.

  3. Continue executing your program by clicking on Go or choosing Execute > Go.

Setting Breakpoints

Set breakpoints to force the debugger to stop execution. You can set simple breakpoints to stop at a line of code, or in a procedure or function.

Set advanced breakpoints to break in C++ classes, track changes in data, break on a condition, break on special events, or create your own custom breakpoints.

You can set and clear breakpoints in the editor window (see Figure 5-2) or the Breakpoints window (see Figure 5-4). In the editor window, you can set or clear a breakpoint at a line of code or in a function. In the Breakpoints window, you can set more complex breakpoints, such as a breakpoint when a signal occurs.

Setting Breakpoints in the Editor Window

To set a location breakpoint:

  1. Click the line where you want the breakpoint.

  2. Click the Stop At button.

    The line is highlighted in red to indicate the breakpoint is set. If the line selected is not an executable line of source code, the debugger sets the breakpoint at the next line after the specified line that is executable.

To set a function breakpoint:

  1. Select the name of the function where you want the breakpoint.

  2. Click the Stop In button.

    A message in the message area tells you that the breakpoint is set.

To remove a breakpoint, do the following:

  1. Move the pointer to the line containing the breakpoint you want to remove.

  2. Click the Clear At button to remove all breakpoints on the line.

Setting Breakpoints in the Breakpoints Window

To open the Breakpoints window, shown in Figure 5-4, choose Windows > Breakpoints or Execute > Set Breakpoints in the Debugging window.

To set a location breakpoint:

  1. If the Details pane is not in view, click the Add/Change Breakpoint button.

  2. Choose At Location from the Event list and type the file name and the line number in the text box, such as Foo.cc:21.

  3. If it is not already set, choose Stop from the Action list.

  4. Click Add.

    The line is highlighted in red to indicate the breakpoint is set. If the line selected is not an executable line of source code, the debugger sets the breakpoint at the next line after the specified line that is executable.

To set a function breakpoint:

  1. If the Details pane is not in view, click the Add/Change Breakpoint button.

  2. Choose In Function from the Event list and type the function or procedure name in the text box.

  3. If it is not already set, choose Stop from the Action list.

  4. Click Add.

    The breakpoint is added to the list of currently active breakpoints.

To remove a breakpoint, do one of the following:

Disable and re-enable breakpoints as you move through your program.

Figure 5-4 Breakpoints Window

Graphic

Scrolling list 

Shows the breakpoints and tracepoints assigned in your program. A breakpoint or tracepoint can be in one of three states: -- Enabled, indicated by a red stop sign -- Disabled, indicated by a gray, crossed-out stop sign 

-- Executed, indicated by an arrow 

Delete button 

Deletes the breakpoint or tracepoint from the source code and removes it from the scrolling list. 

Delete All button 

Deletes all breakpoints and tracepoints from the source code and removes them from the scrolling list. 

Enable button 

Enables the selected breakpoint or tracepoint and changes its glyph to a red stop sign. 

Disable button 

Disables the selected breakpoint or tracepoint and changes its glyph to a gray, crossed-out stop sign. 

Disable All button 

Disables all breakpoints or tracepoints listed and changes their glyphs to gray, crossed-out stop signs. 

Enable All button 

Enables all disabled breakpoints or tracepoints listed and changes their glyphs to red stop signs. 

Show Source button 

Shows the source line of the selected breakpoint or tracepoint in the editor window. 

Add/Change Breakpoints button 

Expands the Breakpoints window. Click to display options for adding or changing a breakpoint in your program. This button toggles to Hide Details. 

Details pane 

Lets you specify the details of a breakpoint.  

Event list 

Allows you to set where and when you want to pause program execution. 

Event text box 

Lets you specify the file name, line number, function name, class name, and so forth, of an event. 

Action list 

Lets you set breakpoint actions such as stopping and 

tracing. 

Option list 

Lets you place additional restrictions on a breakpoint or tracepoint. 

Add button 

Adds a breakpoint or tracepoint with the specified action, event, and option to the source code. In the editor window, a stop sign glyph appears to the left of the source line where the breakpoint or tracepoint appears, and the line is highlighted in red. The breakpoint or tracepoint also appears in the Breakpoints scrolling list. 

Change button 

Updates the event, action, and option of the selected breakpoint or tracepoint. 

Clear button 

Removes all entries from the Event, Action, and Option text boxes. 

Close button 

Closes the Breakpoints window. 

Help button 

Displays online help for the Breakpoints window. 

Collecting Performance Data

While running your program in the debugger, you can use the Sampling Collector to collect performance data and write it to experiment files to be used by the Sampling Analyzer. The Sampling Collector can gather program memory-usage data, execution profile data excluding called function times, and execution profile data including called function times. For more information on collecting and analyzing performance data, see Chapter 6, Analyzing Program Performance,"the Analyzing Program Performance With Sun WorkShop manual, and the Sun WorkShop online help.

You can collect performance data only when you are running in the Sun WorkShop Debugging window and runtime checking is turned off.

To collect performance data:

  1. Choose Windows > Sampling Collector.

  2. Type the complete path name for your experiment file in the Experiment File text box.

  3. Select whether you want to collect data for one run only or for all runs.

    If you run the Sampling Collector for one run only, the Collector shuts off after the experiment is created. If you leave the Collector on for all runs, the Collector remains on even after the experiment is created.

  4. Select the type(s) of data you want to collect.

    If you have chosen to collect Execution Profile data, use the Collect Profile data slider to specify an interval at which the Collector gathers samples.

  5. Select either the Manually, on "New Sample" command radio button or the Periodically radio button to determine when the Collector interrupts data gathering to stop and summarize.

    If you have selected the Periodically button, use the Period slider to define the interval at which the Collector summarizes samples.

  6. Start your program running in the debugger by clicking either Start or Go.

Runtime Checking

Runtime checking, or RTC, allows you to automatically detect runtime errors in an application during the development phase. Using RTC, you can:

To use runtime checking, you must turn on the type of checking you want to use before you execute the program,. Then, when you run the program, runtime checking compiles reports on your memory usage.

Setting Runtime Checking Options

You can customize runtime checking to set defaults for reporting options, error reporting, and stack depth for reports.

To set Runtime Checking options:

  1. Choose Debug > Debugging Options.

    The Debugging Options dialog box is displayed.

  2. Click the Category button and select Runtime Checking.

  3. Click the desired settings in the Runtime Checking category. (For descriptions of the Runtime Checking Options, see "Setting Runtime Checking Options" in the online help.)

Starting Runtime Checking

To turn on memory use checking:

  1. In the Debugging window, choose Windows > Runtime Checking.

    The Runtime Checking window is displayed (see Figure 5-5).

  2. In the Debugging window or the Runtime Checking window, choose Checks > Enable Memuse Checking.

A blue recycling symbol with three arrows pointing in a circle appears in the Debugging window status area and in the Runtime Checking window to remind you that memory use checking is enabled

To turn on memory access checking:

  1. In the Debugging window, choose Windows > Runtime Checking.

    The Runtime Checking window is displayed (see Figure 5-5).

  2. In the Debugging window or the Runtime Checking window, choose Checks > Enable Access Checking.

    A red circle with a white minus sign in the middle (the international Do Not Enter sign) appears in the Debugging window and in the Runtime Checking window to remind you that memory access checking is enabled.

Figure 5-5 Runtime Checking Window

Graphic

File menu 

Provides commands for opening and saving error logs, clearing information from the Runtime Checking window, and closing the window. 

Leaks menu 

Provides commands for controlling the detail level and content of the memory leaks report. 

Blocks menu 

Provides commands for controlling the detail level and content of the memory blocks report. 

Options menu 

Provides a command to display the Runtime Checking category of the Debugging Options dialog box. 

Checks menu 

Provides commands for turning on memory use checking and memory access checking. 

Suppress Last Reported Error button 

Suppresses reporting of the last reported error when you continue running your program. You can use this button after an error is reported and when the program is stopped or interrrupted. 

View Report radio buttons 

Control which runtime checking report is displayed in the output display pane (Access, Memory Leaks, or Memory Blocks) 

Output Display Pane 

Lists the access, memory leak, or memory use report, with a separator line indicating each run of the program or new report requested. 

Tracing Code

Tracing collects information about what is happening in your program and displays it in the Dbx Commands window. Program execution does not stop.

An unfiltered trace displays each line of source code as it is about to be executed, which in all but the simplest programs produces volumes of output.

It is more useful to filter a trace to display information about events in your program. For example, you can trace each call to a function, every member function of a given name, every function in a class, or each exit from a function. You can also trace changes to a variable.

An event is the association of a program event with a debugging action. A typical event is a change in the value of a specified variable. A handler manages debugging events. The trace listing in the Breakpoints window is called a trace handler because it manages the trace, a type of event.

To set up a trace:

  1. In the Breakpoints window, if the Details pane is not displayed, click the Add/Change Breakpoint button.

  2. From the Event list box, choose the type of event you want to trace.

  3. Type any event information, such as the name of a function, or the file name and line number of a location, in the text box.

  4. Choose Action > Trace.

  5. Click Add.


    Note -

    You can control the speed of the trace using the Debugging Behavior category in the Debugging Options dialog box (See the Debugging online help for information on setting debugging options.)


Examining Values and Data

An evaluation is a one-time spot-check of the value of an expression. You can evaluate expressions at any time from the editor window or the Debugging window. You can track the changes in a value each time the program stops using the Data Display window.

The results of an evaluation are listed in the Data History pane of the Debugging window. A dashed line indicates that the evaluation context has changed since the last evaluation. The Data History pane maintains a list of expressions you previously evaluated in a history list. You can clear the Data History pane at any time by choosing Data > Clear History.

To evaluate an expression using the editor window, select the target variable or expression in the source display. Then do one of the following:

The value is shown in the Data History pane. A separator line is inserted into the Data History pane list whenever the evaluation context changes.

To evaluate an expression using the Debugging window:

  1. In the Expression text box, type or paste the variable or expression.

    If the expression you want to examine is visible in the Debugging or editor window, you can select the expression, then choose Data > Evaluate Selected.

  2. Click the Evaluate radio button.

  3. Click the Evaluate button or choose Data > Evaluate Selected.


    Note -

    While the program is stopped, you can change the value of a variable or expression using the Assign button.


Monitoring Data Values

The Data Display window allows you to watch the changes in the value of an expression during program execution. A set of expressions you choose is automatically evaluated every time a program stops executing--at a breakpoint, at a step, and when the program is interrupted. When the value of an expression changes, the value is highlighted in boldface.

From the Data Display window, you can display pop-up windows to view additional information about an expression, giving you control over the information you are viewing.

To monitor the value of an expression:

  1. Open the Data Display window by choosing Windows > Data Display or clicking Display in the Debugging window.

  2. Type an expression in the window by doing one of the following:

    • Type the expression in the Expression text box and click the Display button.

    • Choose Display > New Expression in the Data Display window and type the expression in the text box in the New Expression panel that is displayed.

  3. Place the pointer anywhere in the Data Display window and press the right mouse button to display the Selected Display Item pop-up menu.

    Choose commands from the menu to view context and type information, compare current and previous values, show pointer aliases, and graph arrays.

Examining the Call Stack

The call stack represents all currently active routines--those that have been called but have not yet returned to their respective caller. In the stack, the functions and their arguments are listed in the order that they were called. The initial function (main() for C and C++ programs) is at the top of the Stack pane; the function executing when the program stopped is at the bottom of the Stack pane. This function is known as the stopped in function.

The stopped in function is listed in the Stopped In status line in the Debug Status area of the Debugging window (see Figure 5-1). The source code of the stopped in function is displayed in the editor window with the next line to be executed highlighted in green.

The Evaluation Context line in the status area provides the name of the context function, which determines the scope resolution search order that applies when you provide a symbol name in various debugging operations.

You can examine the call stack by doing any of the following:

Debugging Multithreaded Programs

When a multithreaded program is detected, the Sessions/Threads pane on the Debugging window opens. This pane can be toggled between displaying sessions and displaying threads. For a multithreaded program, the pane lists information about the threads in the currently selected process. The current thread is marked with a green arrow.

To view the context of another thread:

  1. Click the thread in the Threads pane.

    The call stack dynamically updates to reflect the context of the selected thread. The source display also updates. The context function and stopped in function are changed to their respective values for the new thread.

  2. To resume program execution, click Go.

To hide a thread:

  1. Click the thread in the Threads pane.

  2. Choose Threads > Hide Selected.

You can expose threads to help in managing them. To show all hidden threads, choose Threads > Expose Hidden.

Customizing Debugging Sessions

You can set new defaults for debugging performance, output, language, and so on by choosing Debug > Debugging Options. The Debugging Options dialog box is displayed. Using this window, you can customize a debugging session or change defaults for the entire debugger. You can also set many of the defaults by setting environment variables with the dbxenv command.

For detailed information on customizing your debugging session, see Debugging a Program With dbx.

Debugging Processes Simultaneously

You can debug more than one program at a time, with each program connected to a separate debugging session. Following are three examples of programs you may want to debug simultaneously:

Although you are debugging multiple sessions, you can see the context of only one session at a time. The Active Sessions dialog box (see Figure 5-6) maintains a list of all debugging sessions so that you can move between them. The current program is marked with an arrow. When you switch to a different session, the Debugging window, the editor window, the Dbx Commands window, and the other displays reflect the context of the new session.

Figure 5-6 Active Sessions Dialog Box

Graphic

Debugging multiple sessions consumes resources and may slow down your system. The Debugging window states how many active sessions you have. To remove sessions you no longer need, click Quit Session or Detach in the Active Sessions dialog box.

If you are debugging a program, and you ask to debug another program, a message tells you that you are currently debugging a program. You will be prompted to terminate or detach the current session and load a new debugging session, reuse the current session, or debug both sessions. Choose to debug both only if you want to debug both programs simultaneously.

Managing Sessions

During a Sun WorkShop session, you can debug any number of programs. A list of these programs is maintained in the Active Sessions dialog box and in the Sessions Display in the Debugging window, so you can easily terminate, detach, quit, or move between programs. The current program is marked with an arrow.

To manage your sessions using the Active Sessions dialog box:

  1. In the Debugging window, choose Debug > Manage Sessions.

    The Active Sessions dialog box opens.

  2. Select a program from the scrolling list.

  3. Click one of the following buttons:

     Set Current Makes the selected program the current program. The Stack pane, the editor window, and other displays update to reflect the context of the selected program.
     Terminate Terminates the program without terminating the debugging session.
     Detach Detaches the selected program without terminating the program or the debugging session.
     Quit Session Terminates the selected program and removes the debugging session. If you have only one session and you click this button, the session is removed and the Debugging window notes that there are no debugging sessions.

  4. Click Close.

To manage your sessions in the Sessions display of the Debugging window:

  1. If the Sessions/Threads Pane is not open, drag the sash above the Stack Pane to open it.

  2. If the pane is showing the Threads Display, click the Sessions radio button at the top of the pane.


    Note -

    Be careful when debugging multiple programs. Debugging more than two programs may slow down your system considerably. Always be sure to terminate, detach, or quit a session you no longer need.


Quitting a Debugging Session

Debugging multiple sessions can consume resources and slow down your system. If you no longer need a debugging session, use Quit Session to detach a running process or terminate a loaded process. The debugging session is not preserved.

To quit the current debugging session:

  1. In the Debugging window, choose Debug > Manage Sessions.

  2. From the list, select the session you want to quit.

  3. Click Quit Session.


    Note -

    The Terminate command terminates debugging of the current process, but preserves the debugging session. When you load another program, it should load faster than the first one you loaded because the session is already started. Keeping the debugging session around, however, takes up swap space. If you are running out of swap space, use Quit Session to terminate the program and quit the debugging session.


Debugging a Child Process

When a process forks a child process, you can choose to debug the parent process, the child process, or both. You can also override the normal deletion of all breakpoints from the forked process.

The Sampling Collector is disabled for a forked process.

If you consistently follow the same process across executions, you can bypass the Follow Fork dialog box by designating the default action you want to take.

To set the default for a forked process:

  1. From the Debugging window, choose Debug > Debugging Options.

  2. Choose Category > Forks and Threads.

  3. Click the appropriate radio button:

      Parent The fork is ignored and the parent is followed. This is the default behavior.
     Child Debugging switches to the forked child. The process ID of the current process changes to the child's process ID. The parent continues as if it had been detached, and the child process is suspended as if it had been attached. Use Go or Step Into to execute the child process.
     Both A second debugging session is launched to debug the child process, and becomes the current session. The parent's debugging session remains as an active process. The child process is suspended as if it had been attached.
     Ask User Whenever a fork is detected, the Follow Fork dialog box opens, allowing you to choose between the parent, the child, or both processes at the same time. You can examine the state of your program each time to see which fork you want to follow.

  4. Click OK to apply your choices to the current session, or click Save As Defaults and then click OK to use them as the new defaults.

The selected action occurs whenever the process executes fork().

To allow the child to inherit the parent's breakpoints when the new fork will not execute a different process:

  1. From the Debugging window, choose Debug > Debugging Options.

  2. Choose Category > Forks and Threads.

  3. At Child process inherits parent's breakpoints, click the checkbox to enable it.

  4. Click OK to apply your choices to the current session, or click Save As Defaults and then click OK to save your choices as the new defaults.

Quick Mode

Quick Mode is a debugging feature that allows you to run your program normally but with debugging ready in the background to take over the process at any point. If your program terminates abnormally, the debugger is there to save the program before it core dumps.

If all you want to do is run your program as quickly as possible, but you might still need to do some debugging, select Quick Mode when you start the debugger. The Debugging window opens, but otherwise your program runs exactly as if you were running it from the shell; the symbols for the program are not loaded.

If the program encounters a condition that would cause it to terminate, the debugger switches to Debug Mode, and the symbols for the program are loaded. This causes a delay, but leaves you with an active program and full debugging functionality.

When you are running your program in Quick Mode, you can switch to Debug mode whenever execution is interrupted--for example, at a breakpoint or when you manually interrupt execution by clicking on the Interrupt button.

Advantages of Quick Mode

Quick Mode offers the following advantages:

When to Use Quick Mode

Use Quick Mode when you:

As you debug your program, you can toggle between Debug Mode and Quick Mode to take advantage of the best features of each.

How to Switch to Quick Mode

You can choose to run your program in Quick Mode or Debug Mode whenever you select a program to run or debug.

You can toggle between Quick Mode and Debug Mode for the current program from the Debug menu in the Sun WorkShop main window or in the Debugging window.

If you want to change your defaults so that future programs automatically start in Quick Mode, choose Options > Debugging Options in the Sun WorkShop main window. Then choose Debugging Performance from the Category list in the Debugging Options window and click Save As Defaults.

Quick Mode Example

Suppose you made a change to a program and are confident that the change works. After rebuilding the program, you choose Quick Mode from the Debug menu, so that the program runs with minimal overhead. As this is the first time you have run or debugged a program since opening Sun WorkShop, there is a slight delay as the Debugging window opens.

You start your program by clicking the Start button or choosing Execute > Start in the Debugging window. It runs normally until it encounters a segmentation fault.

Before the program can terminate and create a core dump, Sun WorkShop switches into Debug Mode and loads the symbols for your program. You now have access to the full debugging functionality of Sun WorkShop and can debug the program as if you had started debugging in Debug Mode. Eventually, after making many changes, fixing them, and continuing, you rebuild your program.

You again select Quick Mode before running the program.

This time, no initial pause is noticeable, but your program appears to be stuck in an infinite loop. Clicking on the Interrupt button stops the program and loads the debugging symbols. You can now view data values, set breakpoints, and do any other needed debugging actions to track down your bug.

Convinced the third time is the charm, you rebuild your program, re-enable Quick Mode, and run the program again. Your program runs without a flaw.

Exiting Debugging

To quit all processes currently under the control of Sun WorkShop and close all debugging windows, choose Debug > Exit Debugging in the Debugging window.

If you want to close the Debugging window without quitting the processes under the control of Sun WorkShop, choose Debug > Close. The processes under the control of Sun WorkShop continue running, using memory and CPU time, and Sun WorkShop continues to store data on these processes.