[Digital logo]
[HR]

OpenVMS Debugger Manual


Previous | Contents

Key to Example 16-4:

  1. Identifying information about the task.
  2. Bulletin-type information about something unusual.
  3. Next execution PC value and start routine.
  4. Task scheduling policy.
  5. Stack storage information:
  6. Minimum and maximum addresses of the task stack.
  7. Task (thread) control block information. The task value is the address, in hexadecimal notation, of the task control block.
  8. The total storage used by the task. Adds together the task control block size, the number of reserved bytes, the top guard size, and the storage size.

    Figure 16-1 shows a task stack.

    Figure 16-1 Diagram of a Task Stack



    The SHOW TASK/STATISTICS command reports some statistics about all tasks in your program. Example 16-5 shows the output of the SHOW TASK/STATISTICS/FULL command for a sample program with DECthreads tasks. This information enables you to measure the performance of your program. The larger the number of total schedulings (also known as context switches), the more tasking overhead there is.

    Example 16-5 Sample SHOW TASK/STAT/FULL Display for DECthreads Tasks


    task statistics 
        Total context switches:              0 
        Number of existing threads:          0 
        Total threads created:               0 
    DBG> 
    

    16.4.2 Displaying Task Information About Ada Tasks

    The SHOW TASK/ALL command displays information about all of the tasks of the program that currently exist---namely, tasks that have been created and whose master has not yet terminated (see Example 16-6).

    Example 16-6 Sample SHOW TASK/ALL Display for Ada Tasks


     (1)       (2)   (3)    (4)       (5)            (6)
     task id pri hold state   substate     task object 
    * %TASK 1  7       RUN                SHARE$ADARTL+130428 
      %TASK 2  7  HOLD SUSP  Accept       TASK_EXAMPLE.MOTHER+4 
      %TASK 4  7       SUSP  Entry call   TASK_EXAMPLE.FATHER_TYPE$TASK_BODY.CHILD+4 
      %TASK 3  6       READY              TASK_EXAMPLE.MOTHER) 
    DBG> 
    

    Key to Example 16-6:

    1. The task ID (see Section 16.3.3). An asterisk indicates that the task is a visible task.
    2. The task priority. Ada priorities range from 0 to 15.
      On VAX processors, a task is created with a default priority of 7 unless another value is specified with the pragma PRIORITY.
      On Alpha processors, if time slicing is disabled, a task is created with a default prioity of 7; if time slicing is enabled, then a task is created with an approximate midrange value (unless the pragma PRIORITY is specified).
    3. Whether the task has been put on hold with a SET TASK/HOLD command as explained in Section 16.5.1. Placing a task on HOLD restricts the state transitions it can make after the program is subsequently allowed to execute.
    4. The current state of the task (see Table 16-3). The task that is in the RUN (RUNNING) state is the active task. Table 16-3 lists the state transitions possible during program execution.
    5. The current substate of the task. The substate helps indicate the possible cause of a task's state. See Table 16-5.
    6. A debugger path name for the task object or the address of the task object if the debugger cannot symbolize the task object.

    Table 16-5 Ada Task Substates
    Task Substate Description
    Abnormal Task has been aborted.
    Accept Task is waiting at an accept statement that is not inside a select statement.
    Activating Task is elaborating its declarative part.
    Activating tasks Task is waiting for tasks it has created to finish activating.
    Completed [abn] Task is completed due to an abort statement but is not yet terminated. In Ada, a completed task is one that is waiting for dependent tasks at its end statement. After the dependent tasks are terminated, the state changes to terminated.
    Completed [exc] Task is completed due to an unhandled exception¹ but is not yet terminated. In Ada, a completed task is one that is waiting for dependent tasks at its end statement. After the dependent tasks are terminated, the state changes to terminated.
    Completed Task is completed. No abort statement was issued and no unhandled exception¹ occurred.
    Delay Task is waiting at a delay statement.
    Dependents Task is waiting for dependent tasks to terminate.
    Dependents [exc] Task is waiting for dependent tasks to allow an unhandled exception¹ to propagate.
    Entry call Task is waiting for its entry call to be accepted.
    Invalid state There is an error in the DEC Ada run-time library.
    I/O or AST Task is waiting for I/O completion or some AST.
    Not yet activated Task is waiting to be activated by the task that created it.
    Select or delay Task is waiting at a select statement with a delay
    alternative.
    Select or terminate Task is waiting at a select statement with a terminate alternative.
    Select Task is waiting at a select statement with no else, delay, or terminate alternative.
    Shared resource Task is waiting for an internal shared resource.
    Terminated [abn] Task was terminated by an abort statement.
    Terminated [exc] Task was terminated because of an unhandled exception.¹
    Terminated Task terminated normally.
    Timed entry call Task is waiting in a timed entry call.


    ¹ An unhandled exception is one for which there is no handler in the current frame or for which there is a handler that executes a raise statement and propagates the exception to an outer scope.

    Figure 16-1 shows a task stack.

    The SHOW TASK/FULL command provides detailed information about each task selected for display. Example 16-7 shows the output of this command for a sample Ada task.

    Example 16-7 Sample SHOW TASK/FULL Display for an Ada Task


    (1)  task id     pri hold state   substate          task object 
      * %TASK 2      7       RUN                    TASK_EXAMPLE.MOTHER+4 
     
    (2)       Waiting entry callers: 
               Waiters for entry BOGUS: 
                   %TASK 4, type: CHILD 
     
    (3)      Task type:      FATHER_TYPE 
            Created at PC:  TASK_EXAMPLE.%LINE 14+22 
            Parent task:    %TASK 1 
            Start PC:       TASK_EXAMPLE.FATHER_TYPE$TASK_BODY 
    (4)      Task control block:          (5) Stack storage (bytes): 
              Task value:   490816            RESERVED_BYTES:     10640 
              Entries:      3                 TOP_GUARD_SIZE:      5120 
              Size:         1488              STORAGE_SIZE:       30720 
    (6)      Stack addresses:                  Bytes in use:         456 
              Top address:  001EB600 
              Base address: 001F2DFC       (7) Total storage:      47968 
    DBG> 
    

    Key to Example 16-7:

    1. Identifying information about the task.
    2. Rendezvous information. If the task is a caller task, it lists the entries for which it is queued. If the task is to be called, it gives information about the kind of rendezvous that will take place and lists the callers that are currently queued for any of the task's entries.
    3. Task context information.
    4. Task control block information. The task value is the address, in decimal notation, of the task control block.
    5. Stack storage information:
      • RESERVED_BYTES gives the storage allocated by the Ada run-time library for handling stack overflow.
      • TOP_GUARD_SIZE gives the storage allocated for guard pages, which provide protection against storage overflow during task execution.
        On VAX processors, you can specify the number of bytes to be allocated as guard pages with the DEC Ada pragmas TASK_STORAGE and MAIN_STORAGE; the number shown by the debugger is the number of bytes allocated (the pragma value is rounded up to an integral number of pages, as necessary). For more information about these pragmas and the top guard storage area, see the DEC Ada documentation.
        On Alpha processors, you can specify the number of bytes to be allocated as guard pages with the DEC Ada pragmas TASK_STORAGE; the number shown by the debugger is the number of bytes allocated (the pragma value is rounded up to an integral number of pages, as necessary). For more information about these pragmas and the top guard storage area, see the DEC Ada documentation.
      • STORAGE_SIZE gives the storage allocated for the task activation.
        On VAX processors, you can specify the number of bytes to be allocated with the T'STORAGE_SIZE representation clause or in the Ada pragma MAIN_STORAGE; the number shown by the debugger is the number of bytes allocated (the value specified is rounded up to an integral number of pages, as necessary). For more information about this representation clause and pragma and about the task activation (working) storage area, see the DEC Ada documentation.
        On Alpha processors, you can specify the number of bytes to be allocated with the T'STORAGE_SIZE representation clause; the number shown by the debugger is the number of bytes allocated (the value specified is rounded up to an integral number of pages, as necessary). For more information about this representation clause and pragma and about the task activation (working) storage area, see the DEC Ada documentation.
      • "Bytes in use:" gives the number of bytes of stack currently allocated.
    6. Stack addresses of the task stack.
    7. The total storage used by the task. Adds together the task control block size, the number of reserved bytes, the top guard size, and the storage size.

      The SHOW TASK/STATISTICS command reports some statistics about all tasks in your program. Example 16-8 shows the output of the SHOW TASK/STATISTICS/FULL command for a sample Ada tasking program on a VAX system. This information enables you to measure the performance of your program. The larger the number of total schedulings (also known as context switches), the more tasking overhead there is.

      Example 16-8 Sample SHOW TASK/STATISTICS/FULL Display for Ada Tasks (VAX Example)


      task statistics 
          Entry calls       = 4       Accepts = 1     Selects = 2 
          Tasks activated   = 3       Tasks terminated   = 0 
          ASTs delivered    = 4       Hibernations       = 0 
          Total schedulings = 15 
              Due to readying a higher priority task = 1 
              Due to task activations                = 3 
              Due to suspended entry calls           = 4 
              Due to suspended accepts               = 1 
              Due to suspended selects               = 2 
              Due to waiting for a DELAY             = 0 
              Due to scope exit awaiting dependents  = 0 
              Due to exception awaiting dependents   = 0 
              Due to waiting for I/O to complete     = 0 
              Due to delivery of an AST              = 4 
              Due to task terminations               = 0 
              Due to shared resource lock contention = 0 
      DBG> 
       
      

      16.5 Changing Task Characteristics

      To modify a task's characteristics or the tasking environment while debugging, use the SET TASK command as shown in the following table:
      Command Description
      SET TASK/ACTIVE Makes a specified task the active task; not for DECthreads (on OpenVMS Alpha or VAX) or Ada on OpenVMS Alpha (see Section 16.3.1).
      SET TASK/VISIBLE Makes a specified task the visible task (see Section 16.3.1).
      SET TASK/ABORT Requests that a task be terminated at the next allowed opportunity. The exact effect depends on the current event facility (language dependent). For Ada tasks, this is equivalent to executing an abort statement.
      SET TASK/PRIORITY Sets a task's priority. The exact effect depends on the current event facility (language dependent).
      SET TASK/RESTORE Restores a task's priority. The exact effect depends on the current event facility (language dependent).
      SET TASK/[NO]HOLD Controls task switching (task state transitions, see Section 16.5.1).
      SET TASK/TIME_SLICE Controls the time slice value or disable time slicing (see Section 16.5.2); supported for VAX Ada only, and not with DECthreads.

      For more information, see the SET TASK command description.

      16.5.1 Putting Tasks on Hold to Control Task Switching

      Task switching might be confusing when you are debugging a program. Placing a task on hold with the SET TASK/HOLD command restricts the state transitions the task can make once the program is subsequently allowed to execute.

      A task placed on hold can enter any state except the RUNNING state. If necessary, you can force it into the RUNNING state by using the SET TASK/ACTIVE command.

      The SET TASK/HOLD/ALL command freezes the state of all tasks except the active task. You can use this command in combination with the SET TASK/ACTIVE command, to observe the behavior of one or more specified tasks in isolation, by executing the active task with the STEP or GO command, and then switching execution to another task with the SET TASK/ACTIVE command. For example:

      DBG> SET TASK/HOLD/ALL
      DBG> SET TASK/ACTIVE %TASK 1
      DBG> GO
         .
         .
         .
      DBG> SET TASK/ACTIVE %TASK 3
      DBG> STEP
         .
         .
         .
      

      When you no longer want to hold a task, use the SET TASK/NOHOLD command.

      16.5.2 Debugging Programs That Use Time Slicing (VAX Ada Only)

      Tasking programs that use time slicing are difficult to debug because time slicing makes the relative behavior of tasks asynchronous. Without time slicing, task execution is determined solely by task priority; task switches are predictable and the behavior of the program is repeatable from one run to the next. With time slicing, task priorities still govern task switches, but tasks of the same priority also take turns executing for a specified period of time. Thus, time slicing causes tasks to execute more independently from each other, and the behavior of a program that uses time slicing might not be repeatable from one run of the program to the next.

      The SET TASK/TIME_SLICE=t command (supported for VAX Ada only) enables you to specify a new time slice or disable time slicing (with SET TASK/TIME_SLICE=0.0). Thus, you can tune the execution of your tasking programs or diagnose problems that depend on the order in which tasks execute.


      Note

      The SET TASK/TIME_SLICE command is supported for VAX Ada only, and not for VAX Ada with DECthreads. If you use the command in an unsupported context, the debugger issues the following error message:
      %DEBUG-E-NOTIMSLI, time slice modification not supported by this event facility 
      

      Note that there is an interaction between time slicing and the debugger watchpoint implementation. When you set watchpoints, the debugger might automatically increase the value of the time-slice interval to 10.0 seconds. Slowing the time-slice rate prevents some problems.

      16.6 Controlling and Monitoring Execution

      The following sections explain how to do the following functions:

      • Set task-specific and task-independent eventpoints (breakpoints, tracepoints, and so on)
      • Set breakpoints and tracepoints on DECthreads-specific task locations.
      • Set breakpoints and tracepoints on Ada-specific task locations.
      • Monitor task events with the SET BREAK/EVENT or SET TRACE/EVENT commands

      16.6.1 Setting Task-Specific and Task-Independent Debugger Eventpoints

      An eventpoint is an event that you can use to return control to the debugger. Breakpoints, tracepoints, watchpoints, and the completion of STEP commands are eventpoints.

      A task-independent eventpoint can be triggered by the execution of any task in a program, regardless of which task is active when the eventpoint is set. Task-independent eventpoints are generally specified by an address expression such as a line number or a name. All watchpoints are task-independent eventpoints. The following are examples of setting task-independent eventpoints:

      DBG> SET BREAK COUNTER
      DBG> SET BREAK/NOSOURCE %LINE 55, CHILD$TASK_BODY
      DBG> SET WATCH/AFTER=3 KEEP_COUNT
      

      A task-specific eventpoint can be set only for the task that is active when the command is entered. A task-specific eventpoint is triggered only when that same task is active. For example, the STEP/LINE command is a task-specific eventpoint: other tasks might execute the same source line and not trigger the event.

      If you use the SET BREAK, SET TRACE, or STEP commands with the following qualifiers, the resulting eventpoints are task specific:

      • /BRANCH
      • /CALL
      • /INSTRUCTION
      • /LINE
      • /RETURN
      • /VECTOR_INSTRUCTION (VAX only)

      Any other eventpoints that you set with those commands and any eventpoints that you set with the SET WATCH command are task independent. The following are examples of setting task-specific eventpoints:

      DBG> SET BREAK/INSTRUCTION
      DBG> SET TRACE/INSTRUCTION/SILENT DO (EXAMINE KEEP_COUNT)
      DBG> STEP/CALL/NOSOURCE
      

      You can conditionalize eventpoints that are normally task-independent to make them task specific. For example:

      DBG> SET BREAK %LINE 11 WHEN (%ACTIVE_TASK=FATHER)
      

      16.6.2 Setting Breakpoints on DECthreads Tasking Constructs

      You can set a breakpoint on a thread start routine. The breakpoint will trigger just before the start routine begins execution. In Example 16-1, this type of breakpoint is set as follows:

      DBG> SET BREAK worker_routine
      

      Unlike Ada tasks, you cannot specify the body of a DECthreads task by name but the start routine is similar.

      Specifying a WHEN clause with the SET BREAK command ensures that you catch the point at which a particular thread begins execution. For example:

      DBG> SET BREAK worker_routine -
      _DBG> WHEN (%CALLER_TASK = %TASK 4)
      

      In Example 16-1, this conditional breakpoint will trigger when the second worker thread begins executing its start routine.

      Other useful places to set breakpoints are just prior to and immediately after condition waits, joins, and locking of mutexes. You can set such breakpoints by specifying either a line number or the routine name.

      16.6.3 Setting Breakpoints on Ada Task Bodies, Entry Calls, and Accept Statements

      You can set a breakpoint on a task body by using one of the following syntaxes to refer to the task body (see Section 16.3.2):

      task-type-identifier$TASK_BODY 
      
      task-identifier$TASK_BODY 
      

      For example, the following command sets a breakpoint on the body of task CHILD. This breakpoint is triggered just before the elaboration of the task's declarative part (also called the task's activation).

      DBG> SET BREAK CHILD$TASK_BODY
      

      CHILD$TASK_BODY is a name for the address of the first instruction the task will execute. It is meaningful to set a breakpoint on an instruction, and hence on this name. However, you must not name the task object (for example, CHILD) in a SET BREAK command. The task-object name designates the address of a data item (the task value). Just as it is erroneous to set a breakpoint on an integer object, it is erroneous to set a breakpoint on a task object.

      You can monitor the execution of communicating tasks by setting breakpoints or tracepoints on entry calls and accept statements.


      Note

      Ada task entry calls are not the same as subprogram calls because task entry calls are queued and may not execute right away. If you use the STEP command to move execution into a task entry call, the results might not be what you expect.

      There are several points in and around an accept statement where you might want to set a breakpoint or tracepoint. For example, consider the following program segment, which has two accept statements for the same entry, RENDEZVOUS:

       8   task body TWO_ACCEPTS is 
       9   begin 
      10      for I in 1..2 loop 
      11         select 
      12            accept RENDEZVOUS do 
      13               PUT_LINE("This is the first accept statement"); 
      14            end RENDEZVOUS; 
      15         or 
      16            terminate; 
      17         end select; 
      18      end loop; 
      19      accept RENDEZVOUS do 
      20         PUT_LINE("This is the second accept statement"); 
      21      end RENDEZVOUS; 
      22   end TWO_ACCEPTS; 
      

      You can set a breakpoint or tracepoint in the following places in this example:

      • At the start of an accept statement (line 12 or 19). By setting a breakpoint or tracepoint here, you can monitor when execution reaches the start of the accept statement, where the accepting task might become suspended before a rendezvous actually occurs.
      • At the start of the body (sequence of statements) of an accept statement (line 13 or 20). By setting a breakpoint or tracepoint here, you can monitor when a rendezvous has started---that is, when the accept statement actually begins execution.
      • At the end of an accept statement (line 14 or 21). By setting a breakpoint or tracepoint here, you can monitor when the rendezvous has completed, and execution is about to switch back to the caller task.

      To set a breakpoint or tracepoint in and around an accept statement, you can specify the associated line number. For example, the following command sets a breakpoint on the start and also on the body of the first accept statement in the preceding example:

      DBG> SET BREAK %LINE 12, %LINE 13
      

      To set a breakpoint or a tracepoint on an accept statement body, you can also use the entry name (specifying its expanded name to identify the task body where the entry is declared). For example:

      DBG> SET BREAK TWO_ACCEPTS$TASK_BODY.RENDEZVOUS
      

      If there is more than one accept statement for an entry, the debugger treats the entry as an overloaded name. The debugger issues a message indicating that the symbol is overloaded, and you must use the SHOW SYMBOL command to identify the overloaded names that have been assigned by the debugger. For example:

      DBG> SHOW SYMBOL RENDEZVOUS
      overloaded symbol TEST.TWO_ACCEPTS$TASK_BODY.RENDEZVOUS 
        overloaded instance TEST.TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__1 
        overloaded instance TEST.TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__2
      

      Overloaded names have an integer suffix preceded by two underscores. For more information on overloaded names, see the debugger's online help (type Help Language_Support Ada).

      To determine which of these overloaded names is associated with a particular accept statement, use the EXAMINE/SOURCE command. For example:

      DBG> EXAMINE/SOURCE TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__1
      module TEST_ACCEPTS 
          12:       accept RENDEZVOUS do
      DBG> EXAMINE/SOURCE TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__2
      module TEST_ACCEPTS 
          19:       accept RENDEZVOUS do
      

      In the following example, when the breakpoint triggers, the caller task is evaluated (see Section 16.3.4 for information about the symbol %CALLER_TASK):

      DBG> SET BREAK TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__2 -
      _DBG> DO (EVALUATE %CALLER_TASK)
      

      The following breakpoint triggers only when the caller task is %TASK 2:

      DBG> SET BREAK TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__2 -
      _DBG> WHEN (%CALLER_TASK = %TASK 2)
      

      If the calling task has more than one entry call to the same accept statement, you can use the SHOW TASK/CALLS command to identify the source line where the entry call was issued. For example:

      DBG> SET BREAK TWO_ACCEPTS$TASK_BODY.RENDEZVOUS__2 -
      _DBG> DO (SHOW TASK/CALLS %CALLER_TASK)
      

      16.6.4 Monitoring Task Events

      The SET BREAK/EVENT and SET TRACE/EVENT commands enable you to set breakpoints and tracepoints that are triggered by task and exception events. For example, the following command sets tracepoints that trigger whenever task CHILD or %TASK 2 makes a transition to the RUN state:

      DBG> SET TRACE/EVENT=RUN CHILD,%TASK 2
      

      When a breakpoint or tracepoint is triggered as a result of an event, the debugger identifies the event and gives additional information.


      Previous | Next | Contents | [Home] | [Comments] | [Ordering info] | [Help]

      [HR]

        4538P028.HTM
        OSSG Documentation
        22-NOV-1996 13:02:13.84
      

      Copyright © Digital Equipment Corporation 1996. All Rights Reserved.

      Legal