Tru64 UNIX
Ladebug Debugger Manual


Previous Contents Index

3.3.5 Setting and Modifying Action Breakpoints

When an action breakpoint triggers, the debugger suspends execution and then executes a specified list of commands.

To set an action breakpoint:

  1. Display the source or instruction line on which you want to set the action breakpoint (see Section 2.1).
  2. Display the Set/Modify Breakpoint dialog box in one of the following ways:
  3. Enter one or more debugger commands in the Action: field of the dialog box. For example: assign x[j]=3; step; print a;
  4. Click on OK. The action breakpoint is now set (see Figure 3-5).

Figure 3-5 Setting an Action Breakpoint


The following procedure modifies an action breakpoint; that is, it can be used to change the command associated with an existing action breakpoint, or to change an unqualified breakpoint into an action breakpoint:

  1. Do one of the following:
  2. Enter one or more debugger commands in the Action: field of the dialog box. For example: assign x[j]=3; step; print a;
  3. Click on OK. The action breakpoint is now modified.

3.3.6 Deleting Breakpoints

After a breakpoint is set, you can delete it.

When you delete a breakpoint, it is no longer listed in the Breakpoint View so that later you cannot activate it from that list. You would have to reset the breakpoint as explained in Section 3.3.2 and Section 3.3.3. The following are procedures to delete breakpoints:

You can use the delete command in the command interface to remove one or more breakpoints.

Example 3-21 shows breakpoints being deleted and the breakpoint status after each deletion.

Example 3-21 Deleting Breakpoints

(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) 

3.4 Setting Tracepoints for Event Notification

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 display, delete, enable, or disable tracepoints, see Section 3.3.2.2.

3.4.1 Tracepoints That Notify You of Function Entry and Exit

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.

Example 3-22 sets a tracepoint at line number 15 of the COBOL program TESTA.

Example 3-22 Setting a Tracepoint

(ladebug) trace at 15
[#3: trace at "testa.cob":15] 

Example 3-23 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).

Example 3-23 Setting a Conditional Tracepoint

(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) 

3.4.2 Tracepoints That Notify You of a Variable Value Change

You can set a tracepoint that prints a message if the value of a variable changes.

Example 3-24 shows the difference between the trace and tracei commands.

Example 3-24 Tracing Variables

(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) 

3.5 Setting Watchpoints to Monitor Variables and Other Program Locations

Watchpoints provide the user with a mechanism to stop program execution when the debugger detects access to a specified memory location. The debugger can detect any access by assignment, modification (only if the value changes), or read. The default is write access. The debugger can watch memory locations in global memory, in a register, or on a stack.

The debugger can detect memory access while executing:

When a watchpoint command detects memory access, the debugger:

  1. Suspends program execution
  2. Prints the watchpoint event
  3. Prints the instruction that accessed the watched memory
  4. Displays old and new values of the accessed memory location
  5. Prints the first line of source code that will be executed when program execution continues (the instruction following the one that triggered the watchpoint).

Watchpoints are displayed with the status command, activated and deactivated with the enable and disable commands, and deleted with the delete command. Watchpoints remain across rerun commands.

3.5.1 Setting Watchpoints for Addresses

A user can specify a watchpoint for an address or address range. Addresses specified can be given in any base, and can be mapped or not yet mapped.

For location watchpoints (watchpoints specifying a start address to watch), the debugger needs to know the size of the data. If the user does not specify an end address or size expression, the default size is 8 bytes. The user can specify a size different from this default by providing a size expression or an end address. The debugger uses the size information to display old and new values in hexadecimal. The debugger can use any size expression that is valid in the current context and language.

On DIGITAL Alpha systems, the largest quantity written by one instruction is one quadword. For a watched address range larger than 8 bytes, the old and new values are displayed for only the quadword aligned, accessed portion of memory. For watchpoints specifying an address range smaller than 8 bytes, the debugger displays the old and new values from the accessed memory address to the end address of the watched range.

Example 3-25 specifies a watchpoint on an address.

Example 3-25 Setting a Watchpoint on an Address

(ladebug)  watch memory 0x140000170  
  [#1: watch memory (write) 0x140000170 to 0x140000177 ] 
  (ladebug) status
  #1 Access memory (write) 0x140000170 to 0x140000177 { stop } 
  (ladebug) run
  [1] Address 0x140000170 was accessed at: 
    [main:12, 0x1200011a8] stq_u  r3, 0(r2)     
          0x140000170: Old value = 0x0000000000000000 
          0x140000170: New value = 0x0000000000000063 
  [1] stopped at [main:11 0x1200011ac] 
       11    for (i=0; i<8; i++) 
  (ladebug)                   
                    

Example 3-26 specifies a watchpoint for a range of addresses.

Example 3-26 Setting a Watchpoint on an Address Range

(ladebug) watch memory 0x1400001a7, 0x140000b2
  [#1: watch memory (write) 0x1400001a7 to 0x1400000b2 ] 
  (ladebug) run
  [1] Address 0x1400001a8 was accessed at: 
    [main:20, 0x1200001284] stq     r3, 0(r2) 
          0x1400001a8: Old value = 0x0000000000000000 
          0x1400001a8: New value = 0x000000000000002a 
   [1] stopped at [main:21 0x120001288] 
       21    intarray[24577] = 22; 
   (ladebug) 
 

Example 3-27 specifies a watchpoint on an address where the size of the data is 4 bytes, and the user wants to detect read access.

Example 3-27 Setting a Watchpoint on an Address to Detect Read Access

(ladebug) watch memory 0x140000190:4 read

Example 3-28 is the same as Example 3-27, but specifies the size of the data with a sizeof expression.

Example 3-28 Setting a Watchpoint on an Address with an Expression

(ladebug) watch memory 0x140000190:sizeof(int) read

Example 3-29 uses the watch memory alias to detect any access within a range of addresses.

Example 3-29 Using the Watch Memory Alias to Set a Watchpoint on an Address Range to Detect Any Access

(ladebug) wm 0x1400001a7, 0x140000b2 any

3.5.2 Setting Watchpoints for Variables

A user can set watchpoints on either static or nonstatic variables.

A static variable is associated with the same memory address throughout execution of the program. You can always set a watchpoint on a static variable throughout execution.

A nonstatic, or local, variable is allocated on the call stack or in a register, and has a value only when its defining routine is active (on the call stack). You can set a watchpoint on a nonstatic variable only when execution is currently suspended within the scope of the defining routine (including any routine called by the defining routine).

When the user enters a watch variable command, the debugger evaluates the variable expression to get its starting address and size. The debugger translates this into an address range, and sets a watchpoint for this range. For a local variable, the debugger fixes the watched stack address range when the user enters the watchpoint. The watchpoint remains in effect as long as it is enabled, even if the local variable is no longer stored at that stack address range.

Example 3-30 illustrates how a variable watchpoint is displayed.

Example 3-30 Setting a Watchpoint on a Variable

(ladebug)  watch variable foo  
[#1: watch variable (write) foo 0x140000170 to 0x140000177] 
(ladebug)  status
#1 Access memory (write) 0x140000170 to 140000177 { stop } 
(ladebug)  run 
[1] Address 0x140000170 was accessed at: 
 [main:12, 0x1200011a8] stq_u   r3, 0(r2) 
        0x140000170: Old value = 0x0000000000000000 
        0x140000170: New value = 0x0000000000000063 
  [1] stopped at [main:11 0x1200011ac] 
       11    for (i=0; i<8; i++) 
  (ladebug) 
                    

Example 3-31 sets a watchpoint for a variable named foo to detect any access by thread 1 in a function named bar, and then executes the where command.

Example 3-31 Setting a Conditional Watchpoint for a Variable

(ladebug)  watch variable foo any thread 1 in bar {where}  

Example 3-32 uses the watch variable alias to set a watchpoint for a variable named foo to detect any access by thread 1 in a function named bar, and then executes the where and show thread commands.

Example 3-32 Using the Watch Variable Alias to Set a Conditional Watchpoint and Execute Commands

(ladebug)  wv foo any thread 1 in bar {where; show thread}  

3.6 Catching Unaligned Data Accesses

Unaligned data can slow program execution. You can use the catch command to cause Ladebug to stop on each unaligned data access or the ignore command so the debugger does not stop.

Enter the catch unaligned command to instruct the debugger to stop when unaligned access occurs in the debuggee process.

Example 3-33 shows the catch unaligned command.

Example 3-33 Catching Unaligned Access

(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).

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.

3.7 Debugging Programs with Stripped Images

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 15.

3.8 Using Environment Variables Within the Debugger

Ladebug provides commands for manipulating the environment of subsequent debuggees with environment variables. From within the debugger, you can use the setenv, unsetenv, export, and printenv commands.

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:

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.

Note

The environment-manipulation commands have no effect on other environments. For example, the debuggee program cannot affect the output of the Ladebug command 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.

If you are familiar with the dbx debugger, it is important to be aware of the following differences:


Previous Next Contents Index