/sys$common/syshlp/DBG$HELP.HLB  —  DEBUG  SET  WATCH
    Establishes a watchpoint at the location denoted by an address
    expression.

    Format

      SET WATCH  address-expression[, . . . ]

                 [WHEN(conditional-expression)]

                 [DO(command[; . . . ])]

1  –  Parameters

 address-expression

    Specifies an address expression (a program location) at which
    a watchpoint is to be set. With high-level languages, this is
    typically the name of a program variable and can include a path
    name to uniquely specify the variable. More generally, an address
    expression can also be a memory address or a register and can
    be composed of numbers (offsets) and symbols, as well as one or
    more operators, operands, or delimiters. For information about
    the operators that you can use in address expressions, see the
    Address_Expressions online help topic.

    Do not specify the asterisk (*)  wildcard character.

 conditional-expression

    Specifies a conditional expression in the currently set language;
    the expression is to be evaluated whenever execution reaches the
    watchpoint. (The debugger checks the syntax of the expressions in
    the WHEN clause when execution reaches the watchpoint, not when
    the watchpoint is set.) If the expression is true, the debugger
    reports that a watchpoint has been triggered. If an action (DO
    clause) is associated with the watchpoint, it will occur at this
    time. If the expression is false, a report is not issued, the
    commands specified by the DO clause (if one was specified) are
    not executed, and program execution is continued.

 command

    Specifies a debugger command to be executed as part of the DO
    clause when watch action is taken. The debugger checks the syntax
    of the commands in a DO clause when it executes the DO clause,
    not when the watchpoint is set.

2  –  Qualifiers

2.1    /AFTER

       /AFTER:n

    Specifies that watch action not be taken until the nth time the
    designated watchpoint is encountered (n is a decimal integer).
    Thereafter, the watchpoint occurs every time it is encountered
    provided that conditions in the WHEN clause are true. The SET
    WATCH/AFTER:1 command has the same effect as SET WATCH.

2.2    /INTO

    Specifies that the debugger is to monitor a nonstatic variable
    by tracing instructions not only within the defining routine, but
    also within a routine that is called from the defining routine
    (and any other such nested calls). The SET WATCH/INTO command
    enables you to monitor nonstatic variables within called routines
    more precisely than SET WATCH/OVER; but the speed of execution
    within called routines is faster with SET WATCH/OVER.

2.3    /OVER

    Specifies that the debugger is to monitor a nonstatic variable
    by tracing instructions only within the defining routine, not
    within a routine that is called by the defining routine. As a
    result, the debugger executes a called routine at normal speed
    and resumes tracing instructions only when execution returns
    to the defining routine. The SET WATCH/OVER command provides
    faster execution than SET WATCH/INTO; but if a called routine
    modifies the watched variable, execution is interrupted only upon
    returning to the defining routine. When you set watchpoints on
    nonstatic variables, SET WATCH/OVER is the default.

2.4    /SILENT

       /SILENT
       /NOSILENT (default)

    Controls whether the "watch . . . " message and the source line
    for the current location are displayed at the watchpoint. The
    /NOSILENT qualifier specifies that the message is displayed. The
    /SILENT qualifier specifies that the message and source line are
    not displayed. The /SILENT qualifier overrides /SOURCE.

2.5    /SOURCE

       /SOURCE (default)
       /NOSOURCE

    Controls whether the source line for the current location is
    displayed at the watchpoint. The /SOURCE qualifier specifies that
    the source line is displayed. The /NOSOURCE qualifier specifies
    that the source line is not displayed. The /SILENT qualifier
    overrides /SOURCE. See also the SET STEP [NO]SOURCE command.

2.6    /STATIC

       /STATIC
       /NOSTATIC

    Enables you to override the debugger's default determination of
    whether a specified variable (watchpoint location) is static or
    nonstatic. The /STATIC qualifier specifies that the debugger
    should treat the variable as a static variable, even though
    it might be allocated in P1 space. This causes the debugger
    to monitor the location by using the faster write-protection
    method rather than by tracing every instruction. The /NOSTATIC
    qualifier specifies that the debugger should treat the variable
    as a nonstatic variable, even though it might be allocated in P0
    space, and causes the debugger to monitor the location by tracing
    every instruction. Be careful when using these qualifiers.

2.7    /TEMPORARY

    Causes the watchpoint to disappear after it is triggered (the
    watchpoint does not remain permanently set).

3  –  Description

    When an instruction causes the modification of a watchpoint
    location, the debugger takes the following actions:

    1. Suspends program execution after that instruction has
       completed execution.

    2. If you specified /AFTER when you set the watchpoint, checks
       the AFTER count. If the specified number of counts has not
       been reached, execution continues and the debugger does not
       perform the remaining steps.

    3. Evaluates the expression in a WHEN clause, if you specified
       one when you set the watchpoint. If the value of the
       expression is false, execution continues and the debugger
       does not perform the remaining steps.

    4. Reports that execution has reached the watchpoint location
       ("watch of . . . ") unless you specified /SILENT.

    5. Reports the old (unmodified) value at the watchpoint location.

    6. Reports the new (modified) value at the watchpoint location.

    7. Displays the line of source code at which execution is
       suspended, unless you specified /NOSOURCE or /SILENT when
       you set the watchpoint or entered a previous SET STEP NOSOURCE
       command.

    8. Executes the commands in a DO clause, if you specified one
       when you set the watchpoint. If the DO clause contains a GO
       command, execution continues and the debugger does not perform
       the next step.

    9. Issues the prompt.

    For high-level language programs, the address expressions you
    specify with the SET WATCH command are typically variable names.
    If you specify an absolute memory address that is associated
    with a compiler-generated type, the debugger symbolizes the
    address and uses the length in bytes associated with that type
    to determine the length in bytes of the watchpoint location. If
    you specify an absolute memory address that the debugger cannot
    associate with a compiler-generated type, the debugger watches 4
    bytes of memory (by default), beginning at the byte identified by
    the address expression. You can change this length, however, by
    setting the type to either WORD (SET TYPE WORD, which changes the
    default length to 2 bytes) or BYTE (SET TYPE BYTE, which changes
    the default length to 1 byte). SET TYPE LONGWORD restores the
    default length of 4 bytes.

    You can set a watchpoint on a range, for example,

    SET WATCH 30000:300018

    The debugger establishes a series of longword watches that cover
    the range.

    You can set watchpoints on aggregates (that is, entire arrays
    or records). A watchpoint set on an array or record triggers
    if any element of the array or record changes. Thus, you do not
    need to set watchpoints on individual array elements or record
    components. Note, however, that you cannot set an aggregate
    watchpoint on a variant record.

    You can also set a watchpoint on a record component, on an
    individual array element, or on an array slice (a range of array
    elements). A watchpoint set on an array slice triggers if any
    element within that slice changes. When setting the watchpoint,
    follow the syntax of the current language.

4  –  Description, Continued...

    The following qualifiers affect what output is seen when a
    watchpoint is reached:

       /[NO]SILENT
       /[NO]SOURCE

    The following qualifiers affect the timing and duration of
    watchpoints:

       /AFTER:n
       /TEMPORARY

    The following qualifiers apply only to nonstatic variables:

       /INTO
       /OVER

    The following qualifier overrides the debugger's determination of
    whether a variable is static or nonstatic:

       /[NO]STATIC

                                   NOTE

       Related commands:

          (ACTIVATE,DEACTIVATE,SHOW,CANCEL) WATCH
          MONITOR
          SET BREAK
          SET STEP [NO]SOURCE
          SET TRACE

5  –  Static and Nonstatic Watchpoints

    Static and Nonstatic Watchpoints

    The technique for setting a watchpoint depends on whether the
    variable is static or nonstatic.

    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 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). Therefore, 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). The watchpoint is canceled when
    execution returns from the defining routine. With a nonstatic
    variable, the debugger traces every instruction to detect any
    changes in the value of a watched variable or location.

    Another distinction between static and nonstatic watchpoints
    is speed of execution. To watch a static variable, the debugger
    write-protects the page containing the variable. If your program
    attempts to write to that page, an access violation occurs and
    the debugger handles the exception, determining whether the
    watched variable was modified. Except when writing to that page,
    the program executes at normal speed.

    To watch a nonstatic variable, the debugger traces every
    instruction in the variable's defining routine and checks the
    value of the variable after each instruction has been executed.
    Since this significantly slows execution, the debugger issues a
    message when you set a nonstatic watchpoint.

    As explained in the next paragraphs, /[NO]STATIC, /INTO, and
    /OVER enable you to exercise some control over speed of execution
    and other factors when watching variables.

    The debugger determines whether a variable is static or nonstatic
    by checking how it is allocated. Typically, a static variable is
    in P0 space (0 to 3FFFFFFF, hexadecimal); a nonstatic variable is
    in P1 space (40000000 to 7FFFFFFF) or in a register. The debugger
    issues a warning if you try to set a watchpoint on a variable
    that is allocated in P1 space or in a register when execution is
    not currently suspended within the scope of the defining routine.

    The /[NO]STATIC qualifiers enable you to override this default
    behavior. For example, if you have allocated nonstack storage
    in P1 space, use /STATIC when setting a watchpoint on a variable
    that is allocated in that storage area. This enables the debugger
    to use the faster write-protection method of watching the
    location instead of tracing every instruction. Conversely, if,
    for example, you have allocated your own call stack in P0 space,
    use /NOSTATIC when setting a watchpoint on a variable that is
    allocated on that call stack. This enables the debugger to treat
    the watchpoint as a nonstatic watchpoint.

    You can also control the execution speed for nonstatic
    watchpoints in called routines by using /INTO and /OVER.

    On Alpha processors, both static and nonstatic watchpoints are
    available. With static watchpoints, the debugger write-protects
    the page of memory in which the watched variable is stored.
    Static watchpoints, therefore, would interfere with the system
    service itself if not for the debugger's use of system service
    interception (SSI).

    If a static watchpoint is in effect then, through system service
    interception, the debugger deactivates the static watchpoint,
    asynchronous traps (ASTs), and thread switching, just before the
    system service call. The debugger reactivates them just after
    the system service call completes, putting the watchpoint, AST
    enabling, and thread switching back to their original state
    and, finally, checking for any watchpoint hits. This behavior
    is designed to allow the system service to run as it normally
    would (that is, without write-protected pages) and to prevent
    the AST code or a different thread from potentially changing the
    watchpointed location while the watchpoint is deactivated. Be
    aware of this behavior if, for example, your application tests to
    see if ASTs are enabled.

    An active static watchpoint can cause a system service to fail,
    likely with an ACCVIO status, if the system service is not
    supported by the system service interception (SSI) vehicle (
    SYS$SSISHR on OpenVMS Alpha systems). Any system service that is
    not in SYS$PUBLIC_VECTORS is unsupported by SSI, including User
    Written System Services (UWSS) and any loadable system services,
    such as $MOUNT.

    When a static watchpoint is active, the debugger write-protects
    the page containing the variable to be watched. A system service
    call not supported by SSI can fail if it tries to write to that
    page of user memory.

    To avoid this failure, do either of the following:

    o  Deactivate the static watchpoint before the service call.
       When the call completes, check the watchpoint manually and
       reactivate it.

    o  Use nonstatic watchpoints. Note that nonstatic watchpoints can
       slow execution.

    If a watched location changes during a system service routine,
    you will be notified, as usual, that the watchpoint occurred.
    Note that, on rare occasions, stack may show one or more debugger
    frames on top of the frame or frames for your program. To work
    around this problem, enter one or more STEP/RETURN commands to
    get back to your program.

    System service interception is on by default, but on Alpha
    processors only, you can disable interception prior to a
    debugging session by issuing the following command:

    $  DEFINE SSI$AUTO_ACTIVATE OFF

    To reenable system service interception, issue one of the
    following commands:

    $  DEFINE SSI$AUTO_ACTIVATE ON
    $  DEASSIGN SSI$AUTO_ACTIVATE

6  –  Global Section Watchpoints

    On Alpha processors, you can set watchpoints on variables or
    arbitrary program locations 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.

    You set a global section watchpoint just as you would set a
    watchpoint on a static variable. However, because of the way the
    debugger monitors global section watchpoints, note the following
    point. When setting watchpoints on arrays or records, 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. When the location is subsequently mapped
    to a global section, the watchpoint is automatically treated
    as a global section watchpoint and an informational message is
    issued. The watchpoint is then visible from each process of the
    multiprocess program.

    Examples

    1.DBG> SET WATCH MAXCOUNT

    This command establishes a watchpoint on the variable MAXCOUNT.

    2.DBG> SET WATCH ARR
      DBG> GO
           . . .
      watch of SUBR\ARR at SUBR\%LINE 12+8
         old value:
          (1):         7
          (2):         12
          (3):         3
         new value:
          (1):         7
          (2):         12
          (3):         28

      break at SUBR\%LINE 14
      DBG>

    In this example, the SET WATCH command sets a watchpoint on
    the three-element integer array, ARR. Execution is then resumed
    with the GO command. The watchpoint triggers whenever any array
    element changes. In this case, the third element changed.

    3.DBG> SET WATCH ARR(3)

    This command sets a watchpoint on element 3 of array ARR (Fortran
    array syntax). The watchpoint triggers whenever element 3
    changes.

    4.DBG> SET WATCH P_ARR[3:5]

    This command sets a watchpoint on the array slice consisting
    of elements 3 to 5 of array P_ARR (Pascal array syntax). The
    watchpoint triggers whenever any of these elements change.

    5.DBG> SET WATCH P_ARR[3]:P_ARR[5]

    This command sets a separate watchpoint on each of elements 3 to
    5 of array P_ARR (Pascal array syntax). Each watchpoint triggers
    whenever its target element changes.

    6.DBG> SET TRACE/SILENT SUB2 DO (SET WATCH K)

    In this example, variable K is a nonstatic variable and is
    defined only when its defining routine, SUB2, is active (on
    the call stack). The SET TRACE command sets a tracepoint on
    SUB2. When the tracepoint is triggered during execution, the
    DO clause sets a watchpoint on K. The watchpoint is then canceled
    when execution returns from routine SUB2. The /SILENT qualifier
    suppresses the "trace . . . " message and the display of source
    code at the tracepoint.

    7.DBG> g
      %DEBUG-I-ASYNCSSWAT, possible asynchronous system service and static
      watchpoint collision break at LARGE_UNION\main\%LINE 24192+60
      DBG> sho call
      module name      routine name     line        rel PC             abs PC
      *LARGE_UNION     main             24192   00000000000003A0    00000000000303A0
      *LARGE_UNION     __main           24155   0000000000000110    0000000000030110
                                                FFFFFFFF80B90630    FFFFFFFF80B90630
      DBG> ex/sour %line 24192
      module LARGE_UNION
      24192:    sstatus = sys$getsyi (EFN$C_ENF, &sysid, 0, &syi_ile, &myiosb, 0, 0);

    In this example, an asynchronous write by SYS$QIO to its IOSB
    output parameter fails if that IOSB is being watched directly
    or even if it simply lives on the same page as an active static
    watchpoint.

    Debugger notices this problem and warns the user about potential
    collisions between static watchpoints and asynchronous system
    services.
Close Help