Document revision date: 30 March 2001
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Debugger Manual


Previous Contents Index

15.16.2 Monitoring Process Activation and Termination

By default, a tracepoint is triggered when a process comes under debugger control and when it performs an image exit. These predefined tracepoints are equivalent to those resulting from entering the SET TRACE/ACTIVATING and SET TRACE/TERMINATING commands, respectively. You can set breakpoints on these events with the SET BREAK/ACTIVATING and SET BREAK/TERMINATING commands.

To cancel the predefined tracepoints, use the CANCEL TRACE/PREDEFINED command with the /ACTIVATING and /TERMINATING qualifiers. To cancel any user-defined activation and termination breakpoints, use the CANCEL BREAK command with the /ACTIVATING and /TERMINATING qualifiers (the /USER qualifier is the default when canceling breakpoints or tracepoints).

The debugger prompt is displayed when the first process comes under debugger control. This enables you to enter commands before the main image has started execution, as with a one-process program.

Similarly, the debugger prompt is displayed when the last process performs an image exit. This enables you to enter commands after the program has completed execution, as with a one-process program.

15.16.3 Interrupting the Execution of an Image to Connect It to the Debugger

You can interrupt a debuggable image that is running without debugger control in a process and connect that process to the debugger.

15.16.4 Screen Mode Features for Multiprocess Debugging

By default, the source, instruction, and register displays show information about the visible process.

By using the /PROCESS qualifier with the DISPLAY command, you can create process-specific displays or make existing displays process specific, respectively. The contents of a process-specific display are generated and modified in the context of that process. You can make any display process specific except for the PROMPT display. For example, the following command creates the automatically updated source display SRC_3, which shows the source code where execution is suspended in process 3:


2> DISPLAY/PROCESS=(3) SRC_3 AT RS23 -
2> SOURCE (EXAM/SOURCE .%SOURCE_SCOPE\%PC)

Assign attributes to process-specific displays in the same way as for displays that are not process specific. For example, the following command makes display SRC_3 the current scrolling and source display; that is, the output of SCROLL, TYPE, and EXAMINE/SOURCE commands are then directed at SRC_3:


2> SELECT/SCROLL/SOURCE SRC_3

If you enter a DISPLAY/PROCESS command without specifying a process, the specified display is then specific to the process that was the visible process when you entered the command. For example, the following command makes display OUT_X specific to process 2:


2> DISPLAY/PROCESS OUT_X

In a multiprocess configuration, the predefined tracepoint on process activation automatically creates a new source display and a new instruction display for each new process that comes under debugger control. The displays have the names SRC_n and INST_n, respectively, where n is the process number. These displays are initially marked as removed. They are automatically deleted on process termination.

Several predefined keypad key sequences enable you to configure your screen with the process-specific source and instruction displays that are created automatically when a process is activated. Key sequences that are specific to multiprocess programs are as follows: PF1 KP9, PF4 KP9, PF4 KP7, PF4 KP3, PF4 KP1. See Section A.5 for the general effect of these sequences. Use the SHOW KEY command to determine the exact commands.

15.16.5 Setting Watchpoints in Global Sections (Alpha Only)

On Alpha, you can set watchpoints in global sections. A global section is a region of memory that is shared among all processes of a multiprocess program. A watchpoint that is set on a location in a global section (a global section watchpoint) triggers when any process modifies the contents of that location.

When setting watchpoints on arrays or records, note that performance is improved if you specify individual elements rather than the entire structure with the SET WATCH command.

If you set a watchpoint on a location that is not yet mapped to a global section, the watchpoint is treated as a conventional static watchpoint. For example:


1> SET WATCH ARR(1)
1> SHOW WATCH
watchpoint of PPL3\ARR(1)

When ARR is subsequently mapped to a global section, the watchpoint is automatically treated as a global section watchpoint and an informational message is issued. For example:


1> GO
%DEBUG-I-WATVARNOWGBL, watched variable PPL3\ARR(1) has 
        been remapped to a global section 
predefined trace on activation at routine PPL3 in %PROCESS_NUMBER 2 
predefined trace on activation at routine PPL3 in %PROCESS_NUMBER 3 
watch of PPL3\ARR(1) at PPL3\%LINE 93 in %PROCESS_NUMBER 2 
    93:          ARR(1) = INDEX 
   old value: 0 
   new value: 1 
break at PPL3\%LINE 94 in %PROCESS_NUMBER 2 
   94:           ARR(I) = I

After the watched location is mapped to a global section, the watchpoint is visible from each process. For example:


all> SHOW WATCH
For %PROCESS_NUMBER 1 
  watchpoint of PPL3\ARR(1) [global-section watchpoint] 
For %PROCESS_NUMBER 2 
  watchpoint of PPL3\ARR(1) [global-section watchpoint] 
For %PROCESS_NUMBER 3 
  watchpoint of PPL3\ARR(1) [global-section watchpoint] 
all>

15.16.6 System Requirements for Multiprocess Debugging

Several users debugging multiprocess programs simultaneously can place a load on a system. This section describes the resources used by the debugger, so that you or your system manager can tune your system for this activity.

Note that the discussion covers only the resources used by the debugger. You might also have to tune your system to support the multiprocess programs themselves.

15.16.6.1 User Quotas

Each user needs a PRCLM quota sufficient to create an additional process for the debugger, beyond the number of processes needed by the program.

BYTLM, ENQLM, FILLM, and PGFLQUOTA are pooled quotas. They may need to be increased to account for the debugger process as follows:

15.16.6.2 System Resources

The kernel debugger and main debugger communicate through global sections. Each main debugger requires at least one 65-page global section, through which it communicates with up to 8 kernel debuggers (one per process being debugged). Therefore, the system global-page and global-section parameters (GBLPAGES and GBLSECTIONS, respectively) might need to be increased. For example, if 10 users are using the debugger simultaneously, at least 10 global sections using a total of 650 global pages are required.

15.17 Examples

Example 15-4 and Example 15-5 contain the C code for the server and client programs used in examples throughout this chapter.

Example 15-4 server.c

#include <stdio.h> 
#include <starlet.h> 
#include <cmbdef.h> 
#include <types.h> 
#include <descrip.h> 
#include <efndef.h> 
#include <iodef.h> 
#include <iosbdef.h> 
#include <ssdef.h> 
#include <string.h> 
 
#include "mbxtest.h" 
 
int main (int argc, char **argv) 
{ 
    unsigned int status, write_ef; 
    char line_buf [LINE_MAX_LEN + 1]; 
    iosb myiosb; 
    short mbxchan; 
 
    /* Get event flag.  Look for or create the mailbox. 
     */ 
    status = lib$get_ef (&write_ef); 
    if (!(status & 1)) 
    { 
 fprintf (stderr, "Server unable to get eventflag, 
                                  status = %x", status); 
 return 0; 
    } 
    status = sys$crembx (0, &mbxchan, 0, 0, 0, 0, &mbxname_dsc, 
                                  CMB$M_WRITEONLY, 0); 
    if (!(status & 1)) 
    { 
 fprintf (stderr, "Server unable to open mailbox, 
                                  status = %x", status); 
 return 0; 
    } 
 
    /* Open for business.  Loop looking for and processing requests. 
     */ 
    while (TRUE) 
    { 
 printf ("Input command: "); 
 gets (&line_buf); 
 
 status = sys$clref (write_ef); 
 if (!(status & 1)) 
 { 
     fprintf (stderr, "Client unable to clear read event flag, 
                                  status = %x", status); 
     return 0; 
 } 
 status = sys$qiow (write_ef, mbxchan, 
                                  IO$_SETMODE | IO$M_READERWAIT, &myiosb, 
                           0, 0, 0, 0, 0, 0, 0, 0); 
 
 if ((status) && (myiosb.iosb$w_status)) 
 { 
     status = sys$clref (write_ef); 
     if (!(status & 1)) 
     { 
  fprintf (stderr, "Client unable to clear read event flag, 
                                  status = %x", status); 
  return 0; 
     } 
     if (strlen (line_buf) == 0) 
  status = sys$qio (write_ef, mbxchan, IO$_WRITEOF | IO$M_READERCHECK, &myiosb, 
              0, 0, 0, 0, 0, 0, 0, 0); 
     else 
  status = sys$qio (write_ef, mbxchan, IO$_WRITEVBLK | IO$M_READERCHECK, &myiosb, 
              0, 0, line_buf, strlen (line_buf), 0, 0, 0, 0); 
     if (status) 
     { 
  status = sys$waitfr (write_ef); 
  if ((myiosb.iosb$w_status & 1) && (status & 1)) 
                { 
      if (strlen (line_buf) == 0) 
   break; 
  } 
  else 
      fprintf (stderr, "Server failure during write, 
                             status = %x, iosb$w_status = %x\n", 
               status, myiosb.iosb$w_status); 
     } 
     else 
  fprintf (stderr, "Server failure for write request, 
                             status = %x\n", status); 
 } 
 else 
     fprintf (stderr, "Server failure during wait for reader, 
                             status = %x, iosb$w_status = %x\n", 
               status, myiosb.iosb$w_status);  
    } 
    printf ("\n\nServer done...exiting\n"); 
    return 1; 
} 

Example 15-5 client.c

#include <stdio.h> 
#include <starlet.h> 
#include <cmbdef.h> 
#include <types.h> 
#include <descrip.h> 
#include <efndef.h> 
#include <iodef.h> 
#include <iosbdef.h> 
#include <ssdef.h> 
#include <string.h> 
 
#include "mbxtest.h" 
 
int main (int argc, char **argv) 
{ 
    unsigned int status, read_ef; 
    iosb myiosb; 
    short mbxchan; 
    char line_buf [LINE_MAX_LEN]; 
 
    /* Get event flag.  Look for or create the mailbox. 
     */ 
    status = lib$get_ef (&read_ef); 
 
    if (!(status & 1)) 
    { 
 fprintf (stderr, "Client unable to get eventflag, status = %x", status); 
 return 0; 
    } 
    status = sys$crembx (0, &mbxchan, 0, 0, 0, 0, &mbxname_dsc, CMB$M_READONLY, 0); 
    if (!(status & 1)) 
    { 
 fprintf (stderr, "Client unable to open mailbox, status = %x", status); 
 return 0; 
    } 
 
    /* Loop requesting, receiving, and processing new data. 
     */ 
    memset (&myiosb, 0, sizeof(myiosb)); 
 
    while (myiosb.iosb$w_status != SS$_ENDOFFILE) 
    { 
 status = sys$qiow (read_ef, mbxchan, IO$_SETMODE | IO$M_WRITERWAIT, &myiosb, 
      0, 0, 0, 0, 0, 0, 0, 0); 
 if ((status) && (myiosb.iosb$w_status)) 
 { 
     status = sys$clref (read_ef); 
     if (!(status & 1)) 
     { 
  fprintf (stderr, "Client unable to clear read event flag, status = %x", status); 
  return 0; 
     } 
     status = sys$qio (read_ef, mbxchan, IO$_READVBLK | IO$M_WRITERCHECK, &myiosb, 
          0, 0, line_buf, sizeof(line_buf), 0, 0, 0, 0); 
     if (status) 
     { 
  status = sys$waitfr (read_ef); 
  if ((myiosb.iosb$w_status & 1) && (status & 1)) 
      puts (line_buf); 
  else if ((myiosb.iosb$w_status != SS$_NOWRITER) && 
                             (myiosb.iosb$w_status != SS$_ENDOFFILE)) 
      fprintf (stderr, "Client failure during read, 
                             status = %x, iosb$w_status = %x\n", 
               status, myiosb.iosb$w_status); 
     } 
     else 
  fprintf (stderr, "Client failure for read request, status = %x\n", status); 
 } 
 else 
     fprintf (stderr, "Client failure during wait for writer, 
                             status = %x, iosb$w_status = %x\n", 
               status, myiosb.iosb$w_status); 
 status = sys$clref (read_ef); 
 if (!(status & 1)) 
 { 
     fprintf (stderr, "Client unable to clear read event flag, 
                             status = %x", status); 
     return 0; 
 } 
    } 
    printf ("\nClient done...exiting\n"); 
    return 1; 
} 

The header file included in Example 15-4 and Example 15-5, mbxtest.h is shown below.


$DESCRIPTOR(mbxname_dsc, "dbg$mptest_mbx"); 
 
#define LINE_MAX_LEN 255                 


Chapter 16
Debugging Vectorized Programs (VAX Only)

This chapter describes features of the debugger that are specific to vectorized programs (programs that use VAX vector instructions). Use these features in addition to those explained in other chapters.

The information in this chapter enables you to perform the following tasks:

For additional information that is specific to a vectorized high-level language program, see the associated language documentation. For complete information about vector instructions and vector registers, see the VAX MACRO and Instruction Set Reference Manual.

Notes

  1. Compilers do not generate symbol-table data to associate vector registers with symbols declared in the program. Therefore, no symbolization is available for vector registers during a debugging session. Also, you can access a vector register only in scope 0 (the scope of the routine at the top of the call stack).
  2. The examples in this chapter show how to access elements of a vector register using array syntax (for example, EXAMINE %V1(37)). This syntax is not supported for BLISS. In BLISS, use the SET LANGUAGE command to set the language temporarily to some other language, such as Fortran, then use the array syntax for that language.

16.1 Obtaining Information About the Vector Processor

The SHOW PROCESS/FULL command provides some information about the availability and use of the vector processor on your system. For example:


DBG> SHOW PROCESS/FULL
   .
   .
   .
Vector capable:            Yes 
Vector consumer:           Yes  Vector CPU time:       0 00:03:17.18 
Fast Vector context switches:   0  Slow Vector context switches:      0
   .
   .
   .
DBG>

The Vector capable field can have the following entries:
Vector-Capable Entry Description
Yes The VAX system has a vector processor, and it is available to the process that is running the program.
No (protected) The VAX system has a vector processor, but the process running the program is denied access to the processor.
VVIEF The VAX system does not have a vector processor. It is running the VAX Vector Instruction Emulation Facility (VVIEF). The VVIEF is available to the process that is running the program.
No The VAX system does not have an active vector processor, and the VVIEF is not loaded on the system.

16.2 Controlling and Monitoring the Execution of Vector Instructions

The following sections explain how to perform the following tasks:

16.2.1 Executing the Program to the Next Vector Instruction

To execute the program to the next vector instruction encountered in the program, enter the STEP/VECTOR_INSTRUCTION command.

You can also execute the program to the next vector instruction whose opcode is in a list of opcodes by using the command STEP/INSTRUCTION=(opcode[,...]). For example:


DBG> STEP/INSTRUCTION=(VLDL,VSTL,MOVL)

The SET STEP command enables you to change the default unit of execution of the STEP command as follows:

16.2.2 Setting Breakpoints and Tracepoints on Vector Instructions

To set a breakpoint or a tracepoint that triggers whenever a vector instruction is encountered in the program, enter the SET BREAK/VECTOR_INSTRUCTION or SET TRACE/VECTOR_INSTRUCTION command.

To cancel such breakpoints or tracepoints, enter the command CANCEL BREAK/VECTOR_INSTRUCTION or CANCEL TRACE/VECTOR_INSTRUCTION.

You can also set breakpoints and tracepoints on one or more specific vector instructions by using the /INSTRUCTION=(opcode[,...]) qualifier with the SET BREAK and SET TRACE commands. For example:


DBG> SET BREAK/INSTRUCTION=(VVADDL,VVLEQL)

To cancel such breakpoints and tracepoints, enter the CANCEL BREAK/INSTRUCTION or CANCEL TRACE/INSTRUCTION command.

16.2.3 Setting Watchpoints on Vector Registers

You can set watchpoints on the vector registers (V0 to V15) and on the vector control registers (VCR, VLR, and VMR). Section 16.3.1 identifies these registers and their built-in debugger symbols.

These watchpoints are treated like static watchpoints in that, once set, the watchpoint is active until you cancel it explicitly. In the following example, a watchpoint is set on register VCR:


DBG> SET WATCH %VCR

In the case of VMR and V0 to V15, you can set a watchpoint either on the register aggregate (that is, on all elements of the register), on an individual register element, or on a range of elements (a slice). Use the same technique that you use to set a watchpoint on an array variable. (See Section 3.4.)

For example, the following command sets a watchpoint that triggers if any element of register V5 changes:


DBG> SET WATCH %V5

The following command sets a watchpoint that triggers if element 37 of V2 changes (Fortran array syntax):


DBG> SET WATCH %V2(37)

The following command sets a watchpoint that triggers if any element of V2 in the range from element 5 to 13 changes:


DBG> SET WATCH %V2(5:13)


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
4538PRO_031.HTML