Chapter Contents

Previous

Next
Using the Debugger

Performing Basic Debugger Actions


Running Your Program

The go command starts (or resumes) program execution under the debugger. The program then executes until the next requested breakpoint or action. PF12 is the default PF key assignment for the go command. See go for details.


Stepping Through Your Program


Stepping into Functions, Calls, and Returns

The step command resumes execution and breaks execution again when a hook is reached. step stops for all hooks, including source lines, function calls, and returns, in the context of both the called and the calling function. The format of the step command is

step  [INTEGER] 

The optional INTEGER is a nonnegative decimal integer. Use the INTEGER argument to specify the number of times that you want the step command to be performed. The step command is usually used without an optional INTEGER argument. This is the most common form of the step command and it causes the debugger to continue execution to the next hook. In other words, it is used to single step through your program. PF11 is the default PF key assignment for the step command. See step for more details.

Stepping over Functions

When you issue a continue command, it steps over function calls. The format of the continue command is

continue [INTEGER]

The optional INTEGER is a nonnegative decimal integer. Use the INTEGER argument to specify the number of times that you want the continue command to be performed. When a continue command is issued at a function call, the function is not stepped into. Execution proceeds to the next line hook in the current function, provided that there are no other breakpoints requested before the next hook. PF10 is the default PF key assignment for the continue command. See continue for more details.


Stopping in Your Program


Setting Breakpoints

The break command requests breakpoints at hooks in your program. A common format of the break command is

break HOOK-TYPE

Values for the HOOK-TYPE argument are explained in Using Debugger Commands. The HOOK-TYPE argument can be one of several possible formats. Another format of the break command is

break FUNCTION-NAME entry

This format sets a breakpoint at entry to the function that is specified by the FUNCTION-NAME argument. See break for a complete discussion of all the formats for the break command.

break *
breaks at every line-number hook in a source file that is compiled with debug.

break entry
breaks on entry to all functions.

break calls
breaks at each call to a function and at each return from a function.

break func1 entry when (parm ==5)
breaks on entry to the func1 function when the value of parm1 is 5.

break 66
breaks at line 66 of the current function.

The prefix-area command B breaks on line 66 in Prefix-Area Command B Example and is entered from the prefix area of the line number field. This command can be issued only between the lines that contain the opening and closing braces of a function.

See Prefix-Area Commands for a comprehensive listing of the prefix-area commands.

Prefix-Area Command B Example

[IMAGE]


Setting Temporary Breakpoints

The runto command places a temporary breakpoint at a hook in your program. One format of the runto command is

runto HOOK-TYPE [when (EXPRESSION)]

The hook is identified by the HOOK-TYPE argument. One commonly used HOOK-TYPE is a line number. The when(EXPRESSION) argument causes a break at the specified breakpoint whenever the expression is true.

The runto command can be thought of as a shorthand method of issuing a break command followed by a go command. Use the break and go commands if you want to stop at a hook several times. In contrast, if you want to stop a hook only once, use runto. The runto command works particularly well if you know that the hook is hit several times. The reason is that you do not have to drop the temporary breakpoint that is set by the runto command. However, if your program might be interrupted before it stops for the temporary breakpoint, do not use the runto command. The reason is that the temporary breakpoint is dropped at the interruption.

Breakpoints that are set by the runto command are temporary and are removed the first time the program execution stops. This occurs even if execution stops at another breakpoint before reaching the breakpoint that is specified in the runto command. Issuing a runto command causes the program to run until it hits the breakpoint that is specified, unless execution stops before reaching the breakpoint. See runto for more details. The following are examples of the runto command:

runto main 52
sets a temporary breakpoint at line 52 of the main function and then resumes execution.

runto 75 count 5
sets a temporary breakpoint at line 75 of the current function the fifth time the line-number hook at that line is reached and then resumes execution.


Changing Program Execution

The resume command is an alias for the goto command. It enables you to resume program execution after you correct the cause of an error condition. Also, it can be used to go to any accessible line number or return hook and resume execution from there. The resume command can be used for the following types of error conditions:

See the SAS/C Library Reference, Volume 1 for a discussion of the characteristics of signals.

When you receive a signal or exception of one of these types, you can examine the value of variables. If you issue a resume command, it causes the debugger to discard the signal or exception and resume execution. The location where execution resumes depends on the arguments that you use with the resume command, when you issue the command, and where execution in the program stopped. You cannot resume a library function or a function that is compiled with nodebug. One format of the resume command is

resume [FUNCTION-NAME][LINENO]


Arguments

FUNCTION-NAME is the name of a function. LINENO is a source line number. To illustrate what happens when you issue a resume command with different arguments, consider the following hypothetical case:

   math_a()
    {
    stmt1;                  /* lines of code */
    stmt2;

      .
      .
      .

    p = 0;

 27 if (a == b) *p = d;  /* This line causes a SIGSEGV signal */
      .
      .
      .

 59 strncpy(p, "XYZ",4);  /* Call strcmp, passing p--which is   */
                          /* bad, and a string "XYZ". This line */
                          /* would cause a SIGSEGV signal to    */
                          /* occur in the library strncpy       */
                          /* function                           */


Issuing resume with No Arguments

Suppose a SIGSEGV occurs at line 27. Depending on how math_a is supposed to work, several different errors could be the reason for the SIGSEGV. Perhaps p should not have been set to 0, or perhaps a and b should have been equal. If the problem is that p should not have been 0, you can use assign to give p a correct value and then use resume to try the assignment again. Execution starts at the last hook that was encountered before the code that caused the error condition. So, when the first SIGSEGV is encountered at line 27, resume moves back to the closing parenthesis of if (a == b) and retries the rest of the line.

Issuing resume Followed by a Line Number

Execution is resumed at the first hook in the source line that is identified by LINENO in the abending function. The command resume 27 retries line 27 from the beginning of the if statement.

Suppose p is 0, and a and b are not supposed to be equal. You could use assign to change the value of a or b, and use resume 27 to reexecute the if statement, thereby avoiding the bad assignment to *p.

Issuing resume with a Function Name

Suppose that a SIGSEGV occurs at line 59 in strncpy. resume FUNCTION-NAME resumes execution at the last hook that was executed before the error in the active function (specified by FUNCTION-NAME). In this example, you cannot resume strncpy because strncpy is a library routine. Therefore, resume math_a restarts execution at the last hook in math_a before the call to strncpy.

Issuing resume with a Function Name and a Line Number

When used with a function name and a line number (for example, resume math_a 27) the resume command restarts execution at the first hook in the specified line of the named function.

Use resume with a LINENO argument for an error that occurs in a function call that takes several lines. resume with no arguments only reexecutes the last line of the call; you must issue a resume command with the first line in order to reexecute the entire statement. This is important if you correct the problem by changing a parameter in a line of the call other than the last: for example, if math_a contains the lines

   15 longsub(a,b[i],c,
   16        d,e,f);

If you have a failure in longsub that is due to a problem with b, and if you change [i] and then issue resume math_a, the same old b[i] values are still passed to longsub because b[i] is not reexecuted. You have to issue resume math_a 15 to correct it.

If you issue a go, step, or continue command after the debugger gets control due to a signal, the signal is handled normally, as follows:

Also, if you issue the go, step, or [continue] command after the debugger has caught a C++ exception (issued a catch command), the C++ exception is handled as follows:

See resume for more details on the resume command.


Displaying, Disabling, Dropping, and Ignoring Breakpoints Requests

The query command generates a query list, which is a numbered list of break, catch, trace, ignore, on, and monitor command requests that are currently in effect. When issued with no arguments, the query command produces the numbered list of all requests. See query for more details on the query command.

The disable command disables requests. Requests are identified by the request number as displayed by the query command. One format for the disable command is

disable ACTION-RANGE

ACTION-RANGE is either a single request or a range of request numbers from the query list. To disable a single request, supply the number of the request as the argument ACTION-RANGE. To disable a range of requests, give the range, separated by a colon, as the argument ACTION-RANGE. For example, disable 2:5 disables request numbers 2, 3, 4, and 5.

Once you have disabled a request, the request is not honored until you enable it again. See enable for more information. Disabled requests are marked with an asterisk next to the request number in the query list. See disable for more details on the disable command.

The drop command drops one or more requests. Requests are identified by request number as displayed by the query command. The number that is associated with a dropped command is not reused. Example formats of the drop command are

drop ACTION-RANGE

drop all

The first format of the drop command allows you to drop requests from the query list by number. The ACTION-RANGE argument specifies either a single request number or a range of request numbers. The second form of the drop command allows you to drop all request for the entire program. See drop for details about the drop command.

The ignore command instructs the debugger to ignore requests that are currently in effect. One format of the ignore command is

ignore HOOK-TYPE

Values for the HOOK-TYPE argument are explained in HOOK-TYPE Argument. As discussed in that section, this can be one of several possible formats. One commonly used format is

FUNCTION-NAME line-num1:line-num2

This means to ignore requests at source line range in the specified function (FUNCTION-NAME).

The ignore command is helpful if you want to ignore requests only at a specific line number or line number range. In other words, you can leave a request in effect except for a line range. You can drop the ignore command using drop. See ignore for a description of all the formats for the ignore command.


Displaying Variables and Data

The print command prints the value of various program elements. The print command, when used with the single argument EXPRESSION, displays the expression that is specified in the argument and the value of the expression. The value is displayed according to its type as declared in the source code. This format of the command is

print EXPRESSION

EXPRESSION Argument discusses the types of expressions that can be used with the print command and option formats.

The print command enables you to determine the contents of a scalar or aggregate, inspect function return values, print function parameters, and look at other program elements and objects. PF16 is the default PF key assignment for the print command. See print for details on all the formats that you can use. The whatis command displays the type information that is associated with its argument. One format of the whatis command is

whatis EXPRESSION

EXPRESSION is a valid expression or macro. See EXPRESSION Argument for more information. Used with this argument, whatis displays the type and length of the expression. To display information about macro names, you must compile with dbgmacro. The auto command keyword cmacros does not need to be set.

For example, assume the following declaration for the whatis EXPRESSION:

struct ABC {
			int x;
			double d;
			} new_struct;

	whatis new_struct::x	
  displays:
  int x

See whatis for more details.


Modifying Variables and Data

The assign command is similar to the assignment statement that operates on scalars. One format of the assign command is

assign SCALAR-TYPE-EXPRESSION = VALUE

The assign command assigns the value that is specified by the VALUE argument to the object identified by SCALAR-TYPE-EXPRESSION. As described in SCALAR-TYPE-EXPRESSION Argument, SCALAR-TYPE-EXPRESSION is an expression whose type is arithmetic, pointer, or bit-field. VALUE is an expression whose type is one of the following:

You can assign a value to any scalar expression that is visible at the point where you issue the assign command. For example, after compiling with the dbgmacro option, the following declaration and #define statement assigns 18 to avalue

#define A_MIN 9 
int avalue;
assign avalue = 9 + A_MIN

See assign for a description of all formats for the assign command.


Exiting Your Program

The exit command immediately terminates program execution under the debugger, after closing all program and debugger files. PF3 is the default PF key assignment for the exit command. See exit for details.


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.