This chapter descibes how to use Ladebug from the command interface to execute a program under debugger control and debug the program. Your source language may be C, C++, COBOL, Ada, or Fortran. Your program may have one or more processes or threads.
This chapter describes how to:
pop
command.
This chapter describes basic program control and debugging of single-process applications. For more information on debugging multiprocess applications, see Chapter 20. For information on debugging multithreaded applications, see Chapter 19.
Use the run
and rerun
commands to start
execution of a program under debugger control. Ladebug picks up
any new image on the disk and reloads the latest symbolic debugging
information.
You can run the program with command-line arguments by entering
them immediately after the run
command. Command-line
arguments can include flags and options recognized by the program as
well as input and output redirections.
The rerun
command runs the program with the arguments
last used with the run
command. Example 9-1 shows how to use the run
and
rerun
commands.
(ladebug) run -s > prog.output Thread has finished executing (ladebug) stop in main [#1: stop in main ] (ladebug) rerun [1] stopped at [main:4 0x1200011c0] 4 for (i=1 ; i<3 ; i++) { (ladebug)
If you enter any command-line arguments with the rerun
command, the debugger discards the previous set of arguments and
uses the new arguments.
You can terminate program execution by using the quit
or kill
commands. The quit
command
terminates both the debugger and the debugged process and returns
you to the shell.
The kill
command terminates the debugged process but
leaves the debugger running. Any breakpoints and traces previously
set will still be set. You can rerun the program after it has been
killed.
After program execution suspends at a breakpoint or due to a signal, you can direct the debugger to execute only the next line or to continue execution until the current function or a named function exits.
The step
and next
commands let you
execute your source code line by line in the debugger, which gives
you the opportunity to examine variables and data structures. If
the source-code line contains a function call, and the debugging
information about the function is available to the debugger,
the step
and next
commands behave
differently.
The step
command steps through your program one line
at a time following the flow of control exactly. It steps into the
function call and returns to the debugger prompt with the program
counter pointing at the first line in the function that was called.
In Example 9-2, two step
commands continue executing a Fortran program into lines 10 and 11
after program execution has paused at line 9.
(ladebug) stop at 9 [#2: stop at "squares.f90":9 ] (ladebug) run [2] stopped at [squares_:4 0x1200016dc] 9 DO 10 I = 1, N (ladebug) step stopped at [squares_:10 0x120001710] 10 IF(INARR(I) .NE. 0) THEN (ladebug) step stopped at [squares_:11 0x12000172c] 11 OUTARR(K) = INARR(I)**2
The next
command executes the called function to
completion and returns to the debugger prompt with the program
counter pointing at the source-code line immediately after the line
containing the function call.
If the debugging information for the function is not available
to the debugger, then the debugger will step over the function
regardless of whether the step
or the next
command was used.
When you call a routine with limited symbolic information, you may
not want to step into it. The debugger is under the control of the
debugger variable $stepg0
, which determines whether
Ladebug will step into or bypass the routine. When $stepg0
is set to 0 (the default), the debugger steps over calls to
routines compiled without the option that includes full symbolic
debugging information. This means the debugger behaves as if a
next
command were entered, instead of a step
command.
Setting $stepg0
to 1 causes the debugger to step into
these calls, rather than over them.
Use the cont
command to resume program execution
that has been suspended by a breakpoint or signal. Execution then
continues until the next breakpoint or signal, or until the end of
the program.
By entering a signal parameter value with the cont
command, you can direct the debugger to send a signal to the program
resuming program execution. This feature allows you to test your
program's signal handling characteristics.
The signal parameter values can be either a signal number or a string name (for example, SIGSEGV). If you do not specify a parameter value, the default is 0, which allows the program to continue execution without the signal.
In Example 9-3, a cont
command resumes program execution after program execution is
suspended by a breakpoint.
(ladebug) stop in main [#1: stop in main ] (ladebug) run [1] stopped at [main:4 0x120000b14] 4 for (i=1 ; i<3 ; i++) { (ladebug) cont 1! = 1 2! = 2 Thread has finished executing (ladebug)
Use the goto
command to branch to a specified line
after execution is suspended. The source code between the line at
which execution suspended and the line you specify is not executed.
To branch to a source code line, use the following syntax:
goto line_number
The line_number argument must be a line of source code located in the same function in which execution is suspended.
Example 9-4 shows an example that uses the
goto
command.
(ladebug) list 1:9 1 #include <stdio.h> 2 main() { 3 int i,f; > 4 for (i=1 ; i<3 ; i++) { 5 f = factorial(i); 6 printf("%d! = %d\n",i,f); 7 fflush(stdout); 8 } 9 } (ladebug) goto 6 (ladebug) step stopped at [main:7 0x1200011c0] 7 fflush(stdout); (ladebug)
The debugger lets you place breakpoints in your program. When program execution reaches one of these breakpoints, the debugger can either perform predefined actions and continue program execution or suspend program execution and return control to you. Breakpoints can:
stop
and stopi
commands)
when
and wheni
commands)
stopi
and
wheni
commands are specifically used for machine-level
debugging. As such, breakpoints are set based on machine instruction
addresses rather than line numbers. For more information on machine-
level debugging, see Chapter 18.
Any breakpoints you define remain active until you exit the
debugger, disable them using the disable
command,
or delete them using the delete
command.
Table 9-1 lists the commands used for setting breakpoints.
Command | Description |
---|---|
stop | Without a variable argument, suspends program execution and returns to the prompt. With a variable argument, suspends program execution when a variable changes. |
stop if
| Suspends execution when an expression evaluates to true. |
stop at
| Suspends execution when a specific line number is encountered. |
stopi, stopi if, stopi
at | For machine-level debugging; suspends program execution when the specified variable value changes, when an expression evaluates to true, or when a specified address is encountered. |
stop in
| For C++ programming; see the Command Reference for specific forms of this command. |
Use the stop
and stopi
commands to
set a breakpoint that suspends program execution. When specified
conditions are met, the debugger:
You can then use debugger commands to examine the program state, change program variable values, and continue program execution from the breakpoint.
To determine if program execution should halt, you can base the breakpoint on one or more of the following conditions:
To set a breakpoint that suspends program execution when an
instruction corresponding to a line in the source code is reached,
use the appropriate stop at
command syntax.
stop at line_number stop at "file_name":line_number
The line_number argument specifies the line number in the source code of the current source file.
If the source code for your program spans multiple files, make sure that the file context is set to the correct file before you set your breakpoint. For example:
file file_name
You must use quotation marks around the file_name argument
as shown in the second form. For example, if the file name is
sample.c
and the line number is 4, you type
(ladebug) stop at "sample.c":4
After you enter a breakpoint command, the debugger confirms the breakpoint by displaying it and its reference number. Example 9-5 sets a breakpoint at line number 13 of the current source file.
(ladebug) stop at 13 [#1: stop at "sample.c":13 ] (ladebug) run [1] stopped at [factorial:13 0x120001224] 13 if (i<=1) (ladebug)
To set a breakpoint that suspends program execution when a memory
address is reached, use the stopi at
command.
stopi at address
When program execution reaches the specified address, execution
is suspended and the debugger prints the source instruction
corresponding to the specified address. To specify the address
in hexadecimal format, add the prefix 0x
to the
hexadecimal number. The debugger converts the address to decimal
when it confirms the breakpoint command. Example 9-6 sets a breakpoint at the address of a particular
line in the sample program.
(ladebug) stopi at 0x120000b14 [#1: stopi at 4831841044 ] (ladebug) run [1] stopped at [main:4 0x120000b14] 4 for (i=1 ; i<3 ; i++) { (ladebug)
To set a breakpoint that suspends execution at the first instruction
in a program function, procedure, or statement, use the (stop
in
command.
stop in function
stopi in
command is no longer valid,
and results in an error message. Replace stopi in
in
your code with stopi at
for an address or stop
in
for a routine.
Example 9-7 shows how to set a breakpoint in a function.
(ladebug) stop in factorial [#1: stop in factorial ] (ladebug) run [1] stopped at [factorial:13 0x120001224] 13 if (i<=1) (ladebug)
Functions and procedures in your executable file are usually each
preceded by a prolog that contains information about the function
or procedure but which is not of interest to most programmers while
debugging their programs. The stop in
command halts
program execution after the prolog, at the first real sourcecode
statement.
In Example 9-8 the stop in
command sets a breakpoint at the beginning of an Ada program
procedure named ADD_INTEGERS.
(ladebug) stop in add_integers [2] stop in add_integers (ladebug)run [2] stopped at [add_integers:3 +0x20002a69,0x120002a68] procedure add_integers is
To set a breakpoint that stops program execution when the value of a program variable changes, use one of the following commands:
stop variable stopi variable
The stop
command checks the value of the specified
variable every time program execution enters a function. The
stopi
command checks the value of the specified
variable after every instruction. The stopi
command
enables you to determine precisely where a variable changes value,
but slows program execution.
When you enter a trace,
when,
or
stop
command with a variable as an argument (but not
in a conditional statement), the debugger records the address of the
variable. Instead of looking up the variable name when checking the
variable's value, the debugger dereferences the variable's absolute
address. This ensures that the correct version of the variable is
used regardless of the current context.
If the argument contains a variable as part of a larger expression
that cannot be converted into an address and dereferenced, then the
debugger must look up the variable name rather than dereference the
variable's address. In this case, the debugger does the variable
lookup in the current context, which may not be the context active
at the time the trace,
when,
or stop
command was entered.
Example 9-9 shows how to set a breakpoint on a variable.
(ladebug) stop i [#2: stop if i changes ] (ladebug) run [1] stopped at [main:4 0x120000b14] 4 for (i=1 ; i<3 ; i++) { (ladebug) print i 0 (ladebug) cont Value of i changed before "sample.c":13 Old value = 0 New value = 1 [2] stopped at [factorial:13 0x120000bb8] 13 if (i<=1) (ladebug) print i 1 (ladebug)
To set a breakpoint that suspends program execution when the specified conditional expression evaluates to true, use one of the following commands:
stop if (expression) stopi if (expression)
The debugger accepts any valid conditional expression in the language of the program you are debugging. Breakpoints that contain conditional expressions are sometimes called conditional breakpoints.
The stop if
command checks each time a function
is entered to see if the expression evaluates to true. The
stopi if
command checks after each machine
instruction is executed to see if the expression evaluates
to true. The stopi if
version slows program execution
considerably.
A variable included in a conditional expression may be undefined in the current scope at some time during program execution. If this is the case, the debugger prints an error message and suspends program execution as if the condition evaluated to true. Global variables work best in conditional statements.
Example 9-10 shows how to set a breakpoint with a user-defined expression.
(ladebug) stop if (iter==2) [#1: stop if iter==2 ] (ladebug) run [1] stopped at [doit:20 0x120000e14] 20 ++iter; (ladebug) print iter 2 (ladebug)
In this example, the breakpoint is activated only when the program
variable iter
equals 2.
You can combine the optional conditions to further customize a breakpoint command. By combining the line number or function syntax with a conditional expression, you can create a breakpoint that halts program execution only if a line number or function is reached and an expression evaluates to true. Use one of the following commands to set this type of a breakpoint:
stop at line_number if (expression) stop in function if (expression) stopi at line_number if (expression)
Example 9-11 creates a breakpoint that
stops only if the program is executing the factorial
function and the program variable i
is equal to
2.
(ladebug) stop in factorial if (i==2) [#1: stop in factorial if i==2 ] (ladebug) run 1! = 1 [1] stopped at [factorial:13 0x120000bb8] 13 if (i<=1) (ladebug) print 2 (ladebug)
The when
and wheni
commands let you set
breakpoints that execute debugger commands, (rather than suspend
program execution) when the specified conditions are satisfied. To
describe the conditions of the breakpoint, use the same condition
syntaxes described in Section 9.6.1.
The syntax for the command that executes a set of debugger commands when a particular address or line number is reached is as follows:
when [variable] at line_number {command [; . . . ] }
Use the following syntax for an address-oriented command:
wheni [variable] at address {command [; . . . ] }
The commands in the argument must be enclosed in braces and separated by semicolons. These commands cause the statements in the command list to be executed immediately after the statements at the line number or address specified.
Example 9-12 creates a breakpoint that prints a stack trace when line 16 is reached.
(ladebug) when at 16 {where} [#1: when at "sample.c":16 { where } ] (ladebug) run 1! = 1 [1] when [factorial:16 0x12000123c] >0 0x12000123c in factorial(i=2) sample.c:16 #1 0x120001194 in main() sample.c:5 2! = 2 Thread has finished executing (ladebug)
Example 9-13 creates a breakpoint that
displays the contents of the expression HOLD-CHARS
and
SUB-1
in a COBOL program when line 50 is reached and
then resumes execution.
(ladebug) when at 50 {print chars of hold-chars; print SUB-1; cont;} [#3 when at "testa.cob":50 ( print CHARS of HOLD-CHARS; print SUB-1; ; cont ; } ]
You can use the when
and wheni
commands
to set breakpoints at function entry points, as shown in these
syntax lines:
when [variable] in function {command [; . . . ] } wheni [variable] in function {command [; . . . ] }
Tracepoints instruct the debugger to print a message when certain events occur during program execution. You can use tracepoints to notify you when program execution enters and exits program functions or when program variables change value. Tracepoints do not halt program execution but they do slow it down.
The debugger lets you set the following kinds of tracepoints:
You can base a tracepoint on the following conditions:
To set an entry/exit tracepoint unconditionally, enter either the
trace
or tracei
command at the debugger
prompt. An unconditional tracepoint is useful for following the
execution flow of a program. If you use the tracei
command, the debugger notifies you when each function's prolog
(rather than the function itself) is entered. You can also specify
conditions so tracing occurs only if program execution is:
Use one of the following command syntaxes to establish a conditional tracepoint:
trace at line_number [if (expression)] tracei at address [if (expression)]
The expression argument can be any valid conditional expression in the language of the program being debugged. The expression can contain debugger variables, program variables, and constants.
Example 9-14 sets a tracepoint at line
number 15 of the COBOL program TESTA.
(ladebug) trace at 15 [#3: trace at "testa.cob":15]
Example 9-15 shows a tracepoint that
traces only if the program variable i
is equal to
2
and execution is on line 5. When program execution
reaches line 5, and i
is equal to 2,
the
trace is activated and the debugger prints the current source line
(line 5).
(ladebug) trace at 5 if (i==2) [#1: trace at "sample.c":5 if i==2 ] (ladebug) run 1! = 1 [1] trace [main:5 0x120000b1c] > 5 f = factorial(i); 2! = 2 Thread has finished executing (ladebug)
You can set a tracepoint that prints a message if the value of a variable changes. Use one of the following commands to establish a variable tracepoint:
trace variable tracei variable
When you use the trace
command, the debugger evaluates
the variable when execution enters a function. The debugger prints
a message if the value of the variable is different than the value
associated with that variable when the previously executed function
was entered.
When you use the tracei
command, the debugger
evaluates the variable after each instruction is executed, and
prints a message after the statement in which the value changed.
Example 9-16 shows the difference between
these two commands.
(ladebug) trace i [#2: trace i ] (ladebug) tracei i [#3: tracei i ] (ladebug) step [3] Value of i changed before "sample.c":5 Old value = 0 New value = 1 stopped at [main:5 0x120001188] 5 f = factorial(i); (ladebug) step [2] Value of i changed before "sample.c":13 Old value = 0 New value = 1 stopped at [factorial:13 0x120001224] 13 if (i<=1) (ladebug)
You can also set a conditional tracepoint that notifies you of variable value changes, only if program execution is:
Use one of the following commands to establish a conditional variable tracepoint:
trace variable [at line_number | in function] [if (expression)] tracei variable [at address | in function] [if (expression)]
This section describes the commands used to display, delete, disable, and enable breakpoints and tracepoints. It is written in terms of breakpoints but all of these commands are also applicable to tracepoints.
To list all the breakpoints known to the debugger, enter the
status
command.
To delete, disable, or enable a breakpoint, identify the breakpoint by its reference number. When breakpoints are created, they are associated with a reference number. This reference number is shown when:
status
command
Example 9-17 uses the status
command to display active breakpoints in a COBOL program.
(ladebug) status #1 PC==0x120001e14 in testa "testa.cob":2 {break} #2 PC==0x120001ba4 in TESTB "testa.cob":47 {break} #3 PC==0x120001c1c in TESTB "testa.cob":50 {print CHARS of HOLD-CHARS; print SUB-1; ; cont ; ; }
When a breakpoint is no longer needed, use the delete
command to remove the breakpoint. To delete a single breakpoint,
specify the reference number using the following syntax:
delete number
To delete more than one breakpoint, separate the reference numbers with commas using the following syntax:
delete number [, . . . ]
Example 9-18 shows breakpoints being deleted and the breakpoint status after each deletion.
(ladebug) status #1 PC==0x120001180 in main "sample.c":4 { break } #2 (at Proc entry and if $trace0!=*0x11fffe48){trace-expr i;set $trace0=} #3 if $trace1!=*0x11ffffe48 { trace-expr i; set $trace1 = *0x11ffffe48; } (ladebug) delete 1 (ladebug) status #2 (at Proc entry and if $trace0!=*0x11ffe48) {trace-expr i;set $trace0=} #3 if $trace1!=*0x11ffffe48 { trace-expr i; set $trace1 = *0x11ffffe48; } (ladebug) delete 2,3 (ladebug) status (ladebug)
To delete all breakpoints known to the debugger, use one of the following commands:
delete all delete *
When you disable a breakpoint, the debugger ignores the breakpoint during program execution. A disabled breakpoint does not cause the program to suspend execution.
You can use the following disable
commands to disable
breakpoints:
disable number disable all disable *
The disable *
command has the same effect as
disable all.
It disables all breakpoints and all
traces.
The disabled breakpoint is still displayed by the status
command, but it is listed as disabled. Example 9-19 shows breakpoints being
disabled.
(ladebug) status #1 PC==0x120000b14 in main "sample.c":4 { break } #2 PC==0x120000bb8 in factorial "sample.c":13 { break } #3 PC==0x120000b14 in main "sample.c":4 { break } (ladebug) disable 1 (ladebug) status #1 PC==0x120000b14 in main "sample.c":4 { break } Disabled #2 PC==0x120000bb8 in factorial "sample.c":13 { break } #3 PC==0x120000b14 in main "sample.c":4 { break } (ladebug) disable 2,3 (ladebug) status #1 PC==0x120000b14 in main "sample.c":4 { break } Disabled #2 PC==0x120000bb8 in factorial "sample.c":13 { break } Disabled #3 PC==0x120000b14 in main "sample.c":4 { break } Disabled (ladebug)
Disabled breakpoints remain deactivated until you enter the
enable
command to reactivate the breakpoint. You can
use the following enable
commands to enable disabled
breakpoints:
enable number enable all enable *
Example 9-20 shows the breakpoints that
were disabled earlier and then reactivated with the enable
command.
(ladebug) status #1 PC==0x4001b8 in main "sample.c":4 { break } Disabled #2 PC==0x400250 in factorial "sample.c":13 { break } Disabled #3 PC==0x4001b8 in main "sample.c":4 { break } Disabled (ladebug) enable 2 (ladebug) status #1 PC==0x4001b8 in main "sample.c":4 { break } Disabled #2 PC==0x400250 in factorial "sample.c":13 { break } #3 PC==0x4001b8 in main "sample.c":4 { break } Disabled (ladebug) enable all (ladebug) status #1 PC==0x4001b8 in main "sample.c":4 { break } #2 PC==0x400250 in factorial "sample.c":13 { break } #3 PC==0x4001b8 in main "sample.c":4 { break } (ladebug)
A breakpoint that has been reactivated with the enable
command appears as an active breakpoint in the status list. Note
that the last status list in this example is the same as the first
status list in the preceding example (except for the PC values),
showing three active breakpoints.
The return
command directs the debugger to continue
program execution. The command syntax is as follows:
return [function]
The return
command without any arguments directs the
debugger to continue program execution until the current function
exits. If you enter this command with an argument, the debugger
continues program execution until the specified function returns.
The return
command is also useful for finishing
execution of a function you inadvertently stepped into with the
step
command.
In Example 9-21, the step
command is used to step through program execution. When program
execution enters the factorial
function, the
return
command is used to finish the called function
and return control to the program being debugged.
(ladebug) step stopped at [main:5 0x120001188] 5 f = factorial(i); (ladebug) <Return> stopped at [factorial:13 0x120001224] 13 if (i<=1) (ladebug) return stopped at [main:5 0x120001194] 5 f = factorial(i); (ladebug)
After a breakpoint or a signal suspends program execution, you
can execute a single function in your program by using the
call
command, or by including a function call in
the expression argument of a debugger command. Calling a
function lets you test the function's operation with a specific set
of parameters.
When the function you call completes normally, the debugger restores the stack and current context that existed before the function was called.
While the program counter is saved and restored, calling a function does not shield the program state from alteration if the function you call allocates memory or alters global variables. If the function affects global program variables, for instance, those variables will be permanently changed. Functions compiled without the debugger option to include debugging information may lack important parameter information and are less likely to yield consistent results when called.
The syntax for the call
command is as follows:
call function ([parameter[, . . . ]])
Specify the function as if you were calling the function from within your program. You can use both constants and locally visible variables as calling parameters. If the function you are calling has no parameters, specify empty parentheses.
The call
command executes the specified function with
the parameters you supply and then returns control to you (at the
debugger prompt) when the function returns. The call
command discards the return value of the function. If you embed the
function call in the expression argument of a print
command, the debugger prints the return value after the
function returns.
Example 9-22 shows both methods of calling a function.
(ladebug) call factorial(5) (ladebug) print factorial(5) 120 (ladebug)
In this example, the call
command results in the
return value being discarded while the embedded call passes the
return value of the function to the print
command,
which in turn prints the value. You can also embed the call within
a more involved expression, as shown in Example 9-23.
(ladebug) print 341 + factorial(6) / 2 701 (ladebug)
All breakpoints or tracepoints defined during the session are active when executing a called function. When program execution halts during function execution, you can examine program information, execute one line or instruction, continue execution of the function, or call another function.
When you call a function when execution is suspended in a called function, you are nesting function calls, as shown in Example 9-24.
(ladebug) status #1 PC==0x120001180 in main "sample.c":4 { break } #2 PC==0x12000123c in factorial "sample.c":16 { break } (ladebug) call factorial(5) [2] stopped at [factorial:16 0x12000123c] 16 return (i * factorial(i-1) ); (ladebug) where >0 0x12000123c in factorial(i=5) sample.c:16 (ladebug) print i 5 (ladebug) s stopped at [factorial:13 0x120001224] 13 if (i<=1) (ladebug) call factorial(15) [2] stopped at [factorial:16 0x12000123c] 16 return (i * factorial(i-1) ); (ladebug) where >0 0x12000123c in factorial(i=15) sample.c:16 (ladebug) disable 2 (ladebug) return Called Procedure Returned stopped at [factorial:13 0x120001224] 13 if (i<=1) (ladebug) where >0 0x120001224 in factorial(i=4) sample.c:13 #1 0x12000124c in factorial(i=5) sample.c:16 (ladebug) cont Called Procedure Returned stopped at [main:4 0x120001180] 4 for (i=1 ; i<=3 ; i++) { (ladebug) where >0 0x120001180 in main() sample.c:4 (ladebug)
The Ladebug debugger supports function calls and expression evaluations that call functions, with the following limitations:
int
if the functions are
optimized. If the returns are a different type, try using casts
when calling the optimized functions.
Unaligned data can slow program execution. You can use
thecatch
command to cause Ladebug to stop on each
unaligned data access or the ignore
command so the
debugger does not stop.
catch unaligned
Enter the catch unaligned
command to instruct the
debugger to stop when unaligned access occurs in the debuggee
process. The debugger:
Example 9-25 shows this:
(ladebug) catch unaligned (ladebug) run Unaligned access pid=12538 <unaligned_test> va=140002901 pc=120001168 ra=12000114c type=stl Thread received signal BUS stopped at [main:8 0x12000116c] 8 temp = *j; /* unaligned access */
You can distinguish between the SIGBUS of unaligned access and a normal SIGBUS because of the "unaligned access" message (issued by the kernel).
ignore unaligned
Enter the ignore unaligned
command to instruct the
debugger not to stop when unaligned access occurs. This is the
default.
The unalignment functionality is implemented through the setsysinfo system call and SIGBUS. Ladebug makes the setsysinfo system call in the debuggee process so that unaligned accesses for attached processes are also caught.
Ladebug will preserve the previous user settings when these commands are issued.
If the user program executes a setsysinfo or uac (unaligned access
control flag) that is inconsistent with the catch unaligned
or ignore unaligned
command, however, then the
behavior of these commands will be affected.
If SIGBUS is ignored and then the catch unaligned
command is issued:
(ladebug) ignore sigbus (ladebug) catch unaligned
Warning: SIGBUS is currently being ignored - SIGBUS is being caught to catch Unaligned accesses.
If Ladebug is catching unaligned accesses and then SIGBUS is ignored:
(ladebug) catch unaligned (ladebug) ignore sigbus
Warning: SIGBUS is currently being ignored - Cannot catch Unaligned accesses.
The pop
command removes one or more execution frames
from the call stack. The pop
command undoes the work
already done by the removed execution frames. It does not, however,
reverse side effects such as changes to global variables. You may
need to use the assign
command to restore the values
of global variables.
The pop
command is useful when execution has already
passed an error that needs to be corrected.
The syntax of the command is as follows:
pop [number_of_frames]
The optional argument is the number of execution frames to remove from the call stack. If you do not specify the argument, one frame is removed. If specified, the number must be a positive integer less than or equal to the number of frames currently on the call stack.
It is an error to issue the pop
command when there is
no running program.
The following fragment of a debugger session shows the use of the
pop
command:
Reading symbolic information ...done (ladebug) bp factorial [#1: stop in int factorial(int) ] (ladebug) r Factorial time has begun. [1] stopped at [factorial:30 0x120001524] 30 printf("entered factorial\n"); (ladebug) where >0 0x120001524 in factorial(ii=1) c_listfunc_factorial.c:30 #1 0x12000140c in main() c_listfunc.c:41 (ladebug) pop [1] stopped at [main:41 0x120001410] 41 f = factorial(i); (ladebug) c [1] stopped at [factorial:30 0x120001524] 30 printf("entered factorial\n");
To attach to a running process, first invoke Ladebug with a process
ID number and the matching image file from the command line or from
within Ladebug using the attach
command followed by
the process ID and image file. For information on invoking Ladebug
to attach to a running process, see Section 7.8.9.
After Ladebug attaches to a process, control is returned to
the debugger when the process stops (for example, after having
received a signal). You can also manually return control to the
debugger by pressing Ctrl/C or by setting the debugger variable
$stoponattach
to 1 to stop the attached process.
Use the detach
command to detach the debugger from the
previously attached process, based on the process ID you specify.
Ladebug only detaches the specified process and removes all the
user-specified breakpoints from that process.
The following restrictions apply when you debug an attached process:
run
and rerun
commands are disabled.
quit
command will terminate any process
Ladebug created when invoking the debugger with an image file or
when using the load
image_file command. If
it is attached to any process, Ladebug will detach itself from
the process.
The strip
command removes the symbol table and
relocation information ordinarily attached to the output of the
assembler and loader. If you are debugging a binary image that
has been stripped, only machine-level debugging is supported. For
information on machine-level debugging, see Chapter 18.
Ladebug provides commands for manipulating the environment of subsequent debuggees with environment variables. From within the debugger, you can use the following commands:
setenv [env_variable [value]] export [env_variable [= value]]
setenv
and export
are synonyms.
printenv [env_variable]
unsetenv [env_variable]
Manipulation of Subsequent Environments Without Affecting the Current Environment
The environment-manipulation commands apply to any subsequent debuggee environment but not to the current environment. For example:
% ladebug a.out (ladebug) bpmain; run Stopped in main (ladebug) setenv LD_LIBRARY_PATH /usr/proj/libraries
At this point, the setting of the environment variable LD_LIBRARY_
PATH is not in effect; it does not apply to the current execution
of the file a.out,
which was started by the run
command. The environment variable will be applied after you
create a new debuggee by means of one of the following:
run
command
rerun
command
fork(2)
This functionality is useful because it allows you to have different environments: it allows an environment for processes created by Ladebug that is different from Ladebug's environment, and also different from the environment of the shell from which Ladebug was invoked.
setenv.
Nor can the Ladebug command setenv
affect subsequent debuggee calls to getenv(3),
which, like putenv(3)
and clearenv(3)
,
is an environment manipulation routine in libc.a.
For Ladebug prior to Version 4.0, the only way to set environment variables was to set them in the shell, before invoking the debugger, using one of the following commands:
export,
for the Bourne shell and the Korn
shell
setenv,
for the C shell
The environment thus created in the shell applies to the debugger and also is inherited by any debuggees subsequently created.
Two notable disadvantages of this method are as follows:
LD_LIBRARY_
PATH
can prevent future debugger calls to dlopen(3)
from operating correctly.
Differences from dbx Debugger Functionality
If you are familiar with the dbx
debugger, it is
important to be aware of the following differences:
dbx
debugger also has a setenv
command, which works differently. In dbx,
unlike Ladebug, the setenv
command changes the
debugger's current environment. The current environment is
inherited by any subsequently created debuggee processes.
dbx,
you can use the setenv
command to change the behavior of subsequent commands passed to
the shell with sh.
For example,
(dbx) setenv FOO=value (dbx) sh command-using-FOO
In Ladebug, by contrast, the setenv
command does
not change the current debugger environment, and so the command
does not affect a shell invoked by the sh
command.
In Ladebug, you accomplish the same thing in the following way:
For example,
(ladebug) sh FOO=value; command-using-FOO