C H A P T E R  3

Loading and Executing a Program

This chapter describes how to load and run programs within the Prism environment. It covers the following topics:

To use this chapter most effectively, you should already have an executable program that you want to run within the Prism environment. You can also develop a new program by calling up an editor within the Prism environment; see Chapter 6.


Loading a Program

Before you can execute or debug a program in the Prism environment, you must first load the program into the Prism environment. You can load only one program at a time.

As described in Chapter 2, you can load a program into the Prism environment by specifying its name as an argument to the prism command. If you don't use this method, you can load a program once you are in the Prism environment by using one of the methods discussed next.


procedure icon   To Load a Program From the Menu Bar

1. Choose Open from the File menu or the tear-off region.

A dialog box like the one shown in FIGURE 3-1 appears:

 FIGURE 3-1 Open Program Filter

Screenshot of the Open Program Filter dialog box showing filter, directory and program lists, and the current pathname. Buttons are Open, Filter, Cancel, and Help.

2. Double-click on the program name in the Programs scrollable list (if the name is listed).

Or, you can put its path name into the Selection box, then click on Open. To put the file's path name into the Selection box, you can either type it directly in the box or click on its name in the Programs list. The Programs list contains the executable programs in your current working directory.

Use the Open-Program Filter dialog box to control the display of file names in the Programs list; the box uses standard Solaris filters. For example, you can click on a directory in the Directories list if you want to change to that directory. But the Programs list does not update automatically to show the programs in the new directory. Instead, the filter changes to directory-name/*, indicating that all files in directory-name are to be displayed. Click on Filter to display the file names of the programs. Or simply double-click on the directory name in the Directories list to display the programs in the directory.

If you want to use a different filter, you can edit the Open-Program Filter box directly. For example, change it to directory-name/prog* to display only programs beginning with prog.

3. Click on Cancel or press the Esc key if you decide not to load a program.


procedure icon   To Load a Program From the Command Window

single-step bulletType:

(prism all) load program

Use the name of the executable program as its argument. For example, to load the program myprogram, enter

(prism all) load myprogram

What Happens When You Load a Program

Once a program has been successfully loaded, the following occurs:

You can now issue commands to execute and debug this program.

If the Prism environment cannot find the source file, it displays a warning message in the command window. Select Use from the File menu to specify other directories in which the Prism environment is to search; see Creating a Directory List for Source Files for details.


procedure icon  To Load Subsequent Programs

single-step bulletTo load a new program, perform one of the following:


Associating a Core File With a Loaded Program

You can have the Prism environment associate a core file with a program by specifying its file name after the name of the program on the prism command line.


procedure icon  To Associate a Core File With a Loaded Program

single-step bulletType:

(prism all) core corefile

Where corefile is the name of the corresponding core file.

The Prism environment's core command is not available when using the Prism environment with message-passing programs. Instead, you must specify the name of the process core file from the Prism command line.

In either case, when a program failure results in a core dump, the Prism environment reports the error that caused the core dump and loads the program with a stopped status at the location where the error occurred. You can then work with the program within the Prism environment. You can, for example, examine the stack and print the values of variables. You cannot, however, continue execution from the current location.


procedure icon   To Examine the Core File of a Local Process

You can examine a core file created by a message-passing program from within the Prism environment. However, because only one file will be examined, the Prism environment will be started in scalar mode. The procedure for examining a core file for a local process is as follows:

1. Type:

% prism program corefile

2. Type:

(prism all) where

This produces a stack trace.

3. Type:

(prism all) print variable

This lets you inspect the state of your process at the time the core dump was taken.

Note the following restrictions to this procedure:


Attaching to a Running Message-Passing Process

You can attach the Prism environment to a MP process that has already started.


procedure icon  To Attach to a Running Message-Passing Process

1. Obtain the job ID of the processes.

The following is an example of bjobs output (LSF environment):

host4-0 54 =>bjobs
JOBID USER STAT QUEUE FROM_HOST EXEC_HOST JOB_NAME SUBMIT_TIME
15232 jay  RUN  hpc   host4-0   host4-0   chess    Sep 24 13:35 host4-1

2. Type:

% prism -options [program | - ] job_ID

Note that job_ID is the ID of all the processes (not an individual process ID).

3. Use the -n (or -np, -c, -p) option when you request that the Prism environment attach to a job.

Without one of these options, the Prism environment assumes that the ID number is a process ID rather than a job ID.

For example, the following starts the Prism environment and attaches to the running processes in job 15232:

% prism -n 2 mpiprog 15232

See the LSF Batch User's Guide for further information about bjobs. See the Sun HPC ClusterTools User's Guide for further information about mpps.

You attach to a single process of a message-passing program by specifying its process ID. If you do this, however, you won't be able to view or debug what is happening in the other processes.


procedure icon  To Attach to Multiple Jobs When Starting Prism

When you launch the Prism environment, you can specify a list of jobs to attach. Note that if the list of job IDs belongs to the same executable, the Prism environment starts only one session.

single-step bulletType:

% prism - jid_list


Detaching From a Running Process

A job is automatically detached from the Prism environment if you quit it or run another program. You can detach from the job without leaving the Prism environment by issuing the detach command.

The Prism environment lets you detach only when all the processes in the job are stopped. The detach operation itself sets them all running again, outside control of the debugger.


Executing a Program in the Prism Environment

You start execution of a program in the Prism environment by issuing the run command or choosing the Run or Run (args) selection from the Execute menu. You can attach to a program that is already running by using the attach command. This is described in Attaching to a Running Message-Passing Process.


procedure icon  To Run a Program

single-step bulletPerform one of the following:

  • From the menu bar - If you have no commandline arguments you want to specify, choose Run from the Execute menu. Execution starts immediately. By default, the Run selection is in the tear-off region.
If you have command-line arguments, choose Run (args) from the Execute menu. A dialog box is displayed in which you can specify any command-line arguments for the program. This dialog box is represented in FIGURE 3-1. If you have more arguments than will fit in the input box, your entries scroll to the left. Click on the Run button to start execution.

 FIGURE 3-2 Run (args) Dialog Box

Screenshot of the Run (args) dialog box. Buttons are Run, Cancel, and Help.
  • From the command window - Type the run command, including any arguments to the program on the command line. You can abbreviate the command to r.
If you have already run the program, you can issue the rerun command to run it again. The same argument list you previously passed to the program will be used. In both cases, you can redirect input or output using the standard Solaris redirection operators (< >).

When the program starts executing, the status region displays the message running.

You can continue to interact with the Prism environment while a program is running, but many features will be unavailable. Unavailable selections are grayed out in menus. If you issue a command that cannot be executed while the program is running, it is queued until the program stops.

Program I/O

By default, the Prism environment creates a new window for a program's I/O. This window persists across multiple executions and program loads, giving you a complete history of your program's input and output. If you prefer, you can display I/O in the X terminal from which you invoked the Prism environment. See Resource Descriptions for details.

Status Messages

The Prism environment displays status messages before, during, and after the execution of a program. FIGURE 3-1 lists the various status messages that might be displayed.

TABLE 3-1 Status Messages

Message

Meaning

connected

Prism has connected to other nodes to work on a message-passing program.

connecting

Prism is connecting to other nodes in order to work on a message-passing program.

error

Prism has encountered an internal error.

initial

Prism is starting up without a program loaded.

interrupted

The program has been interrupted.

loading

Prism is loading a program.

not started

The program is loaded but not yet started.

running

The program is running.

stopped

The program has stopped at a breakpoint or signal.

terminated

The program has run to completion and the process has gone away.


Stepping and Continuing Through a Program

When using the Prism environment to debug a multiprocess and/or multithreaded program, menu actions such as Step and Next apply to the processes (or threads) belonging to the current set of processes (or threads).

Waiting for and Interrupting Processes

When debugging multiprocess programs, it can be useful at times to be able to identify when a specific process or set of processes has stopped execution. It can also be useful to be able to interrupt execution of individual processes. The Prism environment meets these needs with the commands wait and interrupt.


procedure icon  To Wait for a Specified Process or Set of Processes to Stop Execution

single-step bulletType:

(prism) wait [argument]

A process is considered to have stopped if it has entered the done, break, interrupted, or error state.

There are two versions of the wait command:

  • Use the syntax wait or wait every to wait for every member of the specified pset to stop. If no pset is specified, the command applies to the current pset.
(prism notx)wait every
waits for every process in the pset notx to stop. The current process will be whatever it would normally be; see The Current Pset. This is the default behavior of the wait command.
  • Use the syntax wait any to wait for any member of the specified pset to stop. If no pset is specified, the command applies to the current pset. When the first process stops, it becomes the current process of this pset.
(prism all) wait any pset foo
waits for the first process in pset foo to stop.

There are corresponding Wait Any and Wait Every selections in the Prism environment's Execute menu. They apply to the processes of the current set.

If you prefer to have the step and next commands wait for processes to finish executing before letting you issue other commands, you can issue them along with the wait command. For example,

(prism all) step; wait

executes the next line, then waits for all processes in the current pset to finish execution.

If you use this command sequence frequently, you can provide an alias for it through the alias command. The Prism environment provides the default alias contw for the following command sequence:

(prism all) cont; wait


procedure icon  To End the Wait

single-step bulletPerform one of the following:

  • Type Control-C; this does not affect processes that are running.
  • Choose Interrupt from the Execute menu; this stops processes that are running, in addition to ending the wait.

procedure icon  To Interrupt the Execution of a Process or Set of Processes

single-step bulletPerform one of the following:

  • Type:
(prism all) interrupt
For example, the following interrupts execution of process 0:
(prism all) interrupt pset 0
If there is a predefined pset called running, type the following to interrupt all the processes in that pset:
(prism all) interrupt pset running
Using the interrupt command resets the predefined pset interrupted so that it includes the newly interrupted processes. Processes leave this pset when they continue execution.
  • Select Interrupt from the Execute menu.
This interrupts all running processes that are in the current pset.

Execution Pointer

When using the Prism environment to debug a scalar program, the > symbol in the line-number region points to the next line to be executed. In a multiprocess or multithreaded program, there can be multiple execution points within the program. The Prism environment marks all the execution points for the processes in the current set with a > in the line-number region or a * character when the current source position is the same as the current execution point.


procedure icon  To Display a Pop-Up Window Showing the Executing Process(es)

single-step bulletShift-click on the execution pointer symbol.

This shows the process(es) for which the symbol is the execution pointer.


procedure icon  To Find Out Execution Status in the Current Process Set

single-step bulletType:

(prism all) pstatus pset_qualifier

This finds out the execution status of the pset specified by the pset_qualifier argument.


procedure icon  To Find Out Execution Status in a Specified Process Set

single-step bulletType:

(prism all) pstatus

This finds out the execution status of processes in the current pset.

Rerunning Spawned Prism Sessions


procedure icon  To Rerun a Multiple Job Session Within the Prism Environment

single-step bulletType"

(prism all) rerun

When issued in the primary Prism session, this command cleans up current secondary Prism sessions (shutting down both the secondary Prism sessions and the debuggee processes) before rerunning the currently loaded program.

The rerun command is not valid when issued in the secondary Prism sessions.

For more information about debugging multiple sessions within the Prism environment, see Enabling Support for Spawned MPI Processes.

Controlling Programs With the Commands-Only Interface


procedure icon  Starting a Program

single-step bulletType:

(prism all) run

This starts a program using the commands-only interface. The program starts up in the background.


procedure icon  Bringing a Program to the Foreground

single-step bulletType:

(prism all) fg

This brings the running program into the foreground. Note that you cannot execute Prism commands while the program is executing in the foreground.


procedure icon  Sending a Program to the Background

single-step bulletType:

Ctrl-Z

This key sequence sends the running program to the background and regains the (prism) prompt.


procedure icon  Quitting a Prism Debugging Session

single-step bulletType:

(prism all) quit

This command terminates the debugging session. Before quitting, the Prism environment kills the debugging process if it was started with run, or the Prism environment will detach from it if the program was previously attached.


Using Psets in the Prism Environment

The Prism environment enables you to view your program at the level of an individual process or individual thread.



Note - To view a program at the process level means to view the program at the level of the main thread.



You can use the Prism environment to view all of the processes (and threads), or subsets of the processes (and threads) that make up the program. For example, at times it may be useful to look at the status of process 0 (or thread 0.1). At other times, you might want to look at all processes or threads that have encountered an error, or at all processes or threads in which the value of a particular variable exceeds a certain number.

Such groups of processes or threads (psets) are often of interest because they have some useful characteristic in common. The Prism environment treats a pset as a unit: For example, you can use the name of a pset as a qualifier for many commands. The command is then executed for each process in the set.

You can view psets in the Psets window, as described in Using the Psets Window and Viewing Pset Contents From the Psets Window.



Note - MPI rank numbers are used to identify processes in psets. In multithreaded programs, the Prism environment identifies threads numerically. For example, the first thread in process 0 is thread 0.1. Do not confuse these numbers with the Solaris process IDs (pids) assigned by the system to the message-passing processes.



The Prism environment provides predefined psets for certain groups of processes (and threads). For example, the set of all processes (and threads) in an error state is a predefined pset. You can also define your own psets, as described in Defining Psets; for example, you can define a pset to be those processes (and threads) in which variable x is greater than 0. To Delete Psets From the Psets Window describes how to delete psets.

Some Prism commands can be directed to apply to specific psets by including pset qualifiers as arguments to those commands. If you don't specify a pset as a qualifier to one of these commands, the command is executed on the current pset. The concept of the current pset is described in The Current Pset. The Current Process describes the current process, which is a distinguished process (or thread) within a pset.



Note - In threaded programs, the Prism environment extends the notion of current process to refer to the current thread of a pset.



Using the Psets Navigator

You can navigate to any defined pset using the pull-down menu and arrow keys on the main MP Prism window. The pset navigator controls are shown at the bottom of FIGURE 3-1.

 FIGURE 3-3 Pset Navigator Controls

Screenshot of a portion of the Prism Graphical User Interface, showing the location of the pset pull-down menu button and arrow keys.

Using the Psets Window

You can use the Psets window to view the current status of the processes in your program and to perform many of the actions associated with psets.


procedure icon  To Display the Psets Window

single-step bulletPerform one of the following operations:

  • From the menu bar - Choose the Psets selection from the Debug menu.
  • From the command window - Type
(prism all) show psets on dedicated

FIGURE 3-4 shows the Psets window for a nonthreaded 16-process message-passing program, including several user-defined psets.

FIGURE 3-5 shows the Psets window for a multithreaded program, including the predefined psets.

 FIGURE 3-4 Psets Window (Nonthreaded)

Screenshot of the Psets window, showing several user-defined psets belonging to a nonthreaded 16-process program.

 FIGURE 3-5 Psets Window (Threaded)

Screenshot of the Psets window, showing predefined psets belonging to a threaded 16-process program.

The various components of the window are described in detail in later sections. Here is a brief overview:

  • The main area of the window shows psets and their members.
  • In nonthreaded psets, processes that are members of a set are shown as colored (or black) cells within a rectangle that represents the entire set of processes that make up the message-passing program.
  • Threads of a threaded pset are shown as colored stripes. By default, threads 2, 3, and 4 in all ranks belong to the hide set. These are auxiliary threads created by any program that is linked with libthread.so and are rarely interesting to a programmer. For further information about hiding threads, see Hiding Threads From Psets.
  • The current process or thread for each pset is shown in a darker shade of the color used in the other squares--gray for noncolor monitors.
  • The current pset is shown in the upper left corner of the window. The name of the current pset and the number of the current process are displayed in the small window on the upper right corner of the control panel.
  • You can cycle through the cycle pset by clicking on the left and right arrows labeled Cycle at the top left of the control panel.
  • If you have many psets and a large number of processes or threads, you can use the Zoom arrows to zoom in or out on particular psets. The box to the left of the arrows shows what part of the entire display you are seeing; you can drag the mouse through this box to pan through the display.
  • You can view and change the current pset and current process or thread via the boxes at the top right of the window.
  • The Options menu at the top left of the window lets you hide, display, create, and delete psets. See the discussions starting with Defining Psets through To Delete Psets From the Psets Window.
  • The File menu lets you close the Psets window.

Predefined Psets

The Prism environment provides the following predefined psets:

  • all - Contains all the processes (and threads) in the program; it is the default pset at start-up. The all pset does not contain processes (or threads) that have terminated or were joined.
  • running - Contains all processes (and threads) that are currently executing.
  • error - Contains all processes (and threads) that have encountered an error.
  • interrupted - Contains the processes (and threads) that were interrupted most recently by the user. See Waiting for and Interrupting Processes for a discussion of the interrupt command and a further explanation of this pset.
  • break - Contains the processes (and threads) that are currently stopped at breakpoints.
  • stopped - Contains all processes (and threads) that are currently stopped. It is the union of the sets error, interrupted, and break.
  • done - Contains all processes (and threads) that have terminated successfully. For user threads (not thread 1), the done set contains only zombie threads (threads that are unjoined). Once a thread is joined, it ceases to exist.

These sets are dynamic; that is, as a program executes, the Prism environment automatically adjusts the contents of each set to reflect the program's current state.

In addition, there are two set names that have special meaning: current and cycle. These are discussed in The Current Pset and The cycle Pset, respectively.

Defining Psets

You can create psets in the Prism environment. This section describes the syntax of pset creation. This syntax provides a convenient shorthand method for entering complicated pset specifications.

Psets can be constructed using one or more of the following syntactical building blocks:

  • An individual process (or thread) number.
  • The name of an existing pset. The new pset will have the same definition as the existing set.
  • A list of process (or thread) numbers. Separate the numbers with commas. Use a colon between two process (or thread) numbers to indicate a range. Use a second colon to indicate the stride to be used within this range.
  • A union, difference, or intersection of psets. To specify the union, use the symbol +, |, or ||. To specify the difference, use the minus sign (-). To specify the intersection, use the symbol &, &&, or *.
  • A snapshot of a pset expression. In a multithreaded program, use the snapshot (pset_expression) argument to define a pset with a constant value that could otherwise change during program execution. For more information about the snapshot intrinsic, see Using Snapshots of Unbounded Psets in Commands.

Note that you can use predefined psets to define new psets. Except for pset all, when you use a predefined pset to define a new pset, the Prism environment uses the instantaneous value of the predefined pset. Thus, even if the predefined pset changes, the user-defined pset remains unchanged until the user forces
reevaluation with a Prism command, such as eval pset.


procedure icon  To Specify a Pset as an Argument to a Command

single-step bulletType:

(prism all) command pset pset_specifier

Put the pset_specifier clause at the end of the command line (but before an on window clause, if any).

(prism all) print x pset error

prints the values of the variable x in the predefined pset error. (See Visualizing Multiple Processes for a discussion of printing variables in the Prism environment.)


procedure icon  To Specify a Pset as a Subset of a Pset Clause

single-step bulletPerform one of the following:

  • Specify an individual process number. An individual process can constitute a pset.
(prism all) print x pset 0
prints the value of x in process 0. If the program is multithreaded, it prints the value of x in all threads in process 0.
  • Specify an individual thread number. An individual thread can constitute a pset.
(prism all) print x pset 0.1
prints the value of x in process 0, thread 1.
  • Specify the name of a pset. Name a pset using the define pset command, as described in Naming Psets.
(prism all) print x pset foo
prints x in the processes you have defined to be members of pset foo.
  • Specify a list of process numbers. Separate the numbers with commas.
(prism all) print x pset 0, 4, 7
prints x in processes 0, 4, and 7.
Ranges and strides are allowed. Use a colon between two process numbers to indicate a range. Use a second colon to indicate the stride to be used within this range.
(prism all) print x pset 0:10
prints x in processes 0 through 10. And
(prism all) print x pset 0:10:2
prints x in processes 0, 2, 4, 6, 8, and 10.
You can also combine comma-separated process numbers and range specifications.
(prism all) print x pset 0, 1, 3:5, 8
prints x in processes 0, 1, 3, 4, 5, and 8.
  • Specify a union, difference, or intersection of psets. To specify the union of two psets, use the symbol +, |, or ||.
(prism all) print x pset 0:2 + 8:10
prints x in processes 0, 1, 2, 8, 9, and 10.
(prism all) print x pset foo | bar
prints x in processes that are members of either pset foo or pset bar.
The Prism environment evaluates the pset expression from left to right. If a process is a member of the first part of the expression, it is not evaluated in the rest of the expression. In the example above, if a process is a member of foo, its value of x is printed; the Prism environment does not test for its membership in bar.
  • Specify the difference of two psets by using a minus sign.
(prism all) print x pset stopped - foo
prints x in all processes that are stopped except those belonging to the pset foo.
  • Specify the intersection of two psets, using the &, &&, or * symbol.
(prism all) print x pset foo & bar
prints x in processes that are members of both pset foo and pset bar. If a process returns false for the first part of the expression, it is not evaluated further. In the example above, if a process is not a member of foo, the Prism environment does not test for its membership in bar; it won't be printed in any case.
  • Specify a condition to be met. Put braces around an expression that evaluates to true or false in each process. Processes in which the expression is true are part of the set.
(prism all)print x pset {y > 1}
prints x in processes where y is greater than 1. Likewise,
(prism all) print x pset all - {y == 1}
prints x in all processes except those in which y is equal to 1.
  • Membership in a some psets can change based on the current state of your program; such a pset is referred to as variable. See To Evaluate Variable Psets to learn how to update the membership of a variable pset.
For this syntax to work, the variable must be active in all processes in which the expression is evaluated. If the variable is not active in a process, you get an error message and the command is not executed. To ensure that the command is executed, use the intrinsic isactive in the pset definition. The expression isactive(variable) returns true if variable is on the stack for a process or is a global.
Thus, you could use this syntax to ensure that x is printed:
(prism all) print x pset stopped && {isactive(x)}

Naming Psets

You can assign a name to a pset. This is convenient if you plan to use the set frequently in your Prism session.

Use the syntax described above in Defining Psets to specify the pset. You can use any name except the names that the Prism environment predefines; see Predefined Psets. The name must begin with a letter; it can contain any alphanumeric character, plus the dollar sign ($) and underscore (_).


procedure icon  To Name a Pset

single-step bulletDo one of the following:

  • From the Psets window - Choose Define Set from the Options menu. A dialog box is displayed that prompts for the name and definition of the pset. Click on Create to create the pset.
  • From the command line - Issue the define pset command.

To create a pset called odd, which contains the odd-numbered processes between 1 and 31, type:

(prism all) define pset odd 1:31:2

To create a pset from the first thread in process one, type:

(prism all) define pset gui_thread 1.1

To create a pset from the second thread in process one, type:

(prism all) define pset io_thread 1.2

To create a pset from an expression that takes the intersection of all processes and threads and subtracts the two psets defined in the two previous examples, type:

(prism all) define pset workers (all.all - gui_thread - io_thread)

To create a pset that consists of all processes in which x is not equal to 0, enter

(prism all) define pset xon {x .NE. 0}

Note that x must be active in all processes for this syntax to work. As described above, you can use the intrinsic isactive to ensure that x is active in the processes that are evaluated. The following example creates a variable pset whose contents will change based on the value of x:

(prism all) define pset xon {isactive(x) && (x .NE. 0)}

Variable psets are discussed in a later section.

Finally, note that all processes must be stopped for this syntax to work. To ensure that the definition applies only to stopped processes, use the following syntax:

(prism all) define pset xon stopped && {isactive(x) && (x .NE. 0)}

Dynamic, user-defined psets are deleted when you reload a program. To get a list of these psets before reloading, issue the command show psets. You can then use this list to help reissue the define pset commands. See Viewing Pset Contents From the Psets Window for more information about show psets.

The Prism environment evaluates the membership of a variable pset when it is defined. If no processes meet the condition, the Prism environment prints appropriate error messages, but the set is defined.


procedure icon  To Evaluate Variable Psets

single-step bulletType:

(prism all) eval pset psetname

The following example evaluates the membership of the pset xon:

(prism all) eval pset xon

This causes the display for the pset to be updated in the Psets window.

Note that this evaluation fails if one of the following is true:

  • Processes are running that need to be polled in evaluating the pset.
  • The pset's definition contains a variable that is not active in any of the processes being polled.

For example, type the following command:

(prism all) define pset foo {x > 0}

You must be certain that all processes are stopped and that x is active on all processes when you type the command:

(prism all) eval pset foo

For greater assurance that the evaluation will succeed, use the following syntax:

(prism all) define pset foo stopped && {isactive(x) && (x > 0)}

The extra information provided ensures that the evaluation takes place only in processes that are stopped and in which x is active.

If an evaluation fails, the membership of the pset remains what it was before you issued the eval pset command.

You can use the eval pset command in event actions; see Events Taking Pset Qualifiers.

Combining Named Psets and Pset Expressions

You can use combinations of named psets and pset expressions to isolate processes and threads of interest, as shown in TABLE 3-2:

TABLE 3-2 Examples of Pset Composition

pset

Contains

pset 1.3

Thread 3 in process 1

pset 1:10.3

Thread 3 in processes 1 to 10

pset 1.1, 2.2:5

Process 1, thread 1 and process 2, threads 2, 3, 4, and 5

pset 1.all

All threads in process 1

pset 1

All threads in process 1

pset .4

Thread 4 in all processes. Same as all.4

pset 1,2.(3,4)

All threads in process 1, threads 3 and 4 in process 2

pset 1,2.3,4

All threads in processes 1 and 4, thread 3 in process 2

pset {isactive(var) && var == 1}

All threads in which the variable var is on the stack for a process (or is a global) and has value 1


Each of the following lines specify the same pset:

pset {var_i == 3} . { var_j == 4}

pset {var_i == 3} & { var_j == 4}

pset {var_i == 3 && var_j == 4}


Viewing Pset Contents From the Psets Window

The easiest way to view the contents of psets is to use the Psets window.

By default, the window displays the current pset (which starts out being the predefined pset all) and the psets break, running, and error. When you create a new pset via the define pset command, that set is also displayed automatically.

The processes within a pset are numbered starting at the upper left, increasing from left to right and then jumping to the next row. You can display information about them as follows:

  • Shift-click on a cell to view the Prism ID number of the process it represents.
  • Shift-click elsewhere in the pset rectangle (for example, on a border) to display all the ID numbers of the processes in the pset.
  • Shift-middle-click on a cell to view the process's Solaris pid and the hostname of the node on which it is running.
  • Shift-middle-click elsewhere in the rectangle to display the entire list of pids and hostnames for the processes in the pset.

procedure icon  To Display a Pset

1. Choose the Show selection from the Options menu in the Psets window.

This displays a list of psets; the predefined psets are at the top, followed by any user-defined set names.

2. Click on a set name, and that set is displayed in the window.


procedure icon  To Hide a Pset

1. Choose the Hide selection from the Options menu.

This displays the list of predefined and user-defined psets.

2. Click on a set name to remove that set from the display.

Note that hiding a pset doesn't otherwise affect its status; it still exists and can be used in commands.

Note also that the Show and Hide submenus include the choices All Sets and all. The All Sets choice refers to all psets; the all choice refers to the predefined pset all.


procedure icon  To View Psets Not Shown in the Display Window

1. Use the navigator rectangle (between the Cycle and the Zoom arrows) to pan through the psets.

The gray box in the rectangle shows the position of the display area relative to all the psets that are to be displayed:

 Screenshot of the graphical box used to control panning through psets.

2. Either drag the box or click at a spot in the rectangle.

The box moves to that spot, and the display window shows the psets in this area of the total display.

To display more psets at the same time, click on the Zoom up arrow to the right of the navigator rectangle. This raises the zoom factor, increasing the size of the boxes that represent the psets. Clicking on the Zoom down arrow decreases the size of these boxes.

Viewing Pset Contents From the Command Line


procedure icon  To Print the Contents of the Specified Pset

single-step bulletType:

(prism all) show pset [psetname]

For example, this command might produce this subsequent response:

(prism all) show pset stopped
The set contains the following processes: 0:3.

The show pset command is discussed further in To Find Out the Current Pset.

The show psets command displays the contents and status of all psets, as shown by the following sample output:

(prism all)show psets
foo: 
    definition = 0:31:2
    members = 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
    current process = 0
break: 
    definition = break
    members = nil
    current process = (none)
done: 
    definition = done
    members = 0:31
    current process = 0
interrupted: 
    definition = interrupted
    members = nil
    current process = (none)
error: 
    definition = error
    members = nil
    current process = (none)
running: 
    definition = running
    members = nil
    current process = (none)
stopped: 
    definition = stopped
    members = nil
    current process = (none)
current: 
    definition = 6, 9, 12
    members = 6,9,12
    current process = 6
cycle: 
    definition = 6, 9, 12
    members = 6,9,12
    current process = 6
all: 
    definition = all
    members = 0:31
    current process = 12

Deleting Psets

You can delete named psets that you have defined. You cannot delete any predefined pset except cycle; see The cycle Pset.


procedure icon  To Delete Psets From the Psets Window

single-step bulletPerform one of the following:

  • From the Psets window - Select Delete from the Options menu. This displays a list of psets that you can delete. Click on the name of the pset you want to delete. If it is currently displayed in the Psets window, it disappears.
  • From the command line - Issue the delete pset command, using a pset qualifier to specify the name of a user-defined pset. For example, this deletes the pset named xon:
(prism all) delete pset xon

See Events Taking Pset Qualifiers for a discussion of the effects of deleting a pset on events that have been defined to affect the members of that set.

The Current Pset

The command syntax described in Defining Psets lets you apply a command to a specific pset. If you don't use this syntax, the command is applied to the current pset; current is a predefined pset name in the Prism environment. In addition, many graphical actions in the Prism environment apply only to the members of the current set.

Note that you cannot change the current pset to one that has no members. If you try to do so, nothing will happen in the Psets window and you will get a message like the following in the history region of the command window:

Cannot set current pset to running -- it is empty.

When a program is first loaded, the current pset is the default pset, all.


procedure icon  To Change the Current Pset

single-step bulletPerform one of the following:

  • From the Psets window - There are several ways of changing the current pset via the Psets window:
    • If the set is displayed in the Psets window, simply double-click anywhere in its display (for example, on its name or in the box beneath its name).
    • Select Set Pset from the Options menu. This displays a list of psets. Click on the name of the set you want to be current.
    • Edit the name of the pset in the box below Current Set, then press Return.
When you change the current set, the new name appears in the Current Set box in the Psets window, and the current set shown at the top left of the psets area changes to reflect the contents of the new set.
  • From the command line, type:
(prism all) pset pset_specifier
For example, the following changes the current pset to foo:
(prism all) pset foo
You can also use the pset command with the pset-specification syntax described in Defining Psets.

procedure icon  To Find Out the Current Pset

single-step bulletPerform one of the following:

  • Look for the name in the Current Set box in the Psets window.
  • Look in the status region in the Prism environment's main window.
  • Type
(prism all) pset
This displays the current set.

procedure icon  To List the Processes in the Current Pset

single-step bulletType:

(prism all) show pset

The Psets window also displays the processes in the current pset. In this example, issuing the show pset command at the Prism commandline causes the Prism Environment to list the processes in the current pset:

(prism foo)show pset
pset 'current' is defined as 'foo'.
The set contains the following processes: 1,2.

Current Pset and Predefined Psets

Predefined Psets describes predefined psets-- sets like running, stopped, and interrupted whose contents the Prism environment automatically updates during execution of the program.

If you specify a predefined pset as the current pset, it becomes a static pset that consists of the processes that are members of the predefined set at the time it is made the current set. To make this clear, the (prism) prompt changes to list the processes that are members of this static set. In this example, if processes 0, 1, and 13 are the only processes that are stopped, the pset command changes the Prism commandline prompt to list the processes 0, 1, and 13:

(prism all)pset stopped
(prism 0:1, 13)show pset
The current set was created by evaluating the pset
'stopped' once at the time when it became the current set.
The set contains the following processes: 0:1, 13.

Output of the show pset command is explicit under these circumstances.

Issuing the pset command with no arguments displays the same information.

Note that the (prism) prompt can become quite long if there are many processes in a current pset derived from a dynamic pset. By default, the prompt length is limited to 25 characters. You can change this default by issuing the set command with the $prompt_length variable, specifying the maximum number of characters to appear in the pset part of the prompt. In this example, the command shortens the prompt long_pset_name to long_pset:

(prism long_pset_name)set $prompt_length=9
(prism long_pset) 

Current Pset and Variable Psets

Defining Psets describes how to create variable psets -- user-defined psets whose membership can change in the course of program execution.


procedure icon  To Update the Membership of a Variable Pset

single-step bulletType:

(prism all) eval pset

If you make a variable pset your current set, its membership is determined by the most recent eval pset command you have executed for the set.

The Current Process

Each pset has a current process, which serves as the scoping point for Prism commands. By default, the process with the lowest rank is the current process. If that process is threaded, its lowest numbered thread is the current process.

The Prism environment uses the current process and current thread in several ways:

  • The Prism environment's source window displays the source that is executing in the current process or current thread.
  • The Prism environment centers the Where graph around the call stack of the current process or current thread.
  • The Prism environment uses the current process or current thread to resolve variable names.

procedure icon  To Change the Current Process

single-step bulletPerform one of the following:

  • From the Psets window - Do either of the following:
    • Click on the cell representing the process in the displayed pset. The cell turns a darker shade of the color used for the other processes.
    • To change the current process in the current pset, you can also edit the number in the box under Process (or Thread if the loaded program is a threaded program) at the top right of the window, then press Return.
  • From the command line - Issue the process command. This is illustrated in the following example:
  • (prism all) process 2
    
    The current process is now 2.
    

The syntax of the process command includes both process number and thread ID, as shown below:

(prism all) process process_number.thread_ID

process_number is the rank of the process that you want to make the current process. thread_ID is the identifying number of the thread in that process that you want to be the current thread.

If you do not specify the thread_ID value, it defaults to the lowest numbered thread on the specified process. This is illustrated in the following example:

(prism all) pset 1:4:2.2:3
(prism 1:4:2.2:3)process 3
(prism 1:4:2.2:3)

This example replaces the pset all with a pset consisting of the processes and threads: 1.2, 1.3, 3.2, and 3.3. In other words, the pset command specifies that the new pset will consist of a subset of processes in the range of 1 through 4. Within this range, the subset is restricted to threads 2 and 3 on those processes that are selected by a process stride of 2.

When the pset command completes execution, the default current process is 1.2. This is the process with the lowest rank and the lowest numbered thread on that process.

The process command on the second line changes the current process to 3.2.


procedure icon  To Print the Current Process of the Current Pset

single-step bulletType:

(prism all) process

Scope in the Prism Environment

When using the Prism environment to debug a message-passing program, the scope of the current process determines the scope for resolving the names of variables.

If a command applies to a pset other than the current set, the Prism environment uses the scope of that set's current process.

It is possible that other members of the pset will have different scopes from that of the current process, or that its scope level will not even exist in these processes. In these cases, you receive an error message when you try to issue a command (for example, print or display) that requires a consistent scope. To solve the problem, you can do one of the following:

  • Restrict your pset so that it contains only members with the same scope.
  • If the current process's scope level does not exist in other processes in the set, you can use the up command to move up its call stack to a point where it has a scope level that does exist in the other processes.
  • If different processes in the set have different scopes, you can issue the up and down commands as needed to ensure that they all have the same scope.

Commands such as pset and process that affect scope print the current function when you issue them.

The cycle Pset

In debugging a message-passing program, you may often want to look, in turn, at each process within a pset . The cycle pset provides you with a convenient way of doing this.


procedure icon  To Create a cycle Pset out of an Existing Pset

single-step bulletType:

(prism all)define pset cycle psetname

If psetname is dynamic, the cycle pset is statically fixed when you create it. You can then cycle through each process in this pset to examine it in turn.

By default, the cycle pset is equivalent to the current pset. For more information about the define pset command, see Defining Psets.

For example,the following copies foo into the cycle pset:

(prism all)define pset cycle foo

Note that changing the cycle pset erases any previous cycling information. For example, if you do the following:

1. Make foo the current set and cycle partway through it.

2. Make bar the current set.

3. Once again make foo the current set.

Then you start at the beginning again when you cycle through the members of foo.


procedure icon  To Cycle Through the Processes in a cycle Pset

single-step bulletPerform one of the following:

  • From the Psets window:

Use the Cycle arrows at the top left of the window to cycle through the members of the cycle set.

Click on the right arrow to cycle up through the members of the set; click on the left arrow to cycle down through the members.

  • From the command line:

Type:

(prism all)cycle

This has the same effect as clicking on the right cycle arrow in the Psets window.

In a nonthreaded program, the cycle command sets the current process to the next one in the current pset. In a threaded program, it sets the current process to be the next valid thread on the current process. If the cycle command is entered when the current thread is the last thread in the process, it steps to the next process in the pset.

In the following example, this Prism session defines a pset, makes it the current set, and then cycles through its members:

(prism all) define pset foo 0:3
(prism all) pset foo
(prism foo) cycle
(prism 1) cycle
(prism 2) cycle
(prism 3) cycle
(prism 0)

  • From the Source-Window pop-up menu:

Choose Cycle from the Source-Window pop-up menu. This advances to the next member of the cycle pset.

Cycle Visualizer Window

The Prism environment includes a Cycle window type for visualizing data. When you print a variable's value to the Cycle window, the value changes to that of the variable in the new process whenever you cycle through the members of the cycle pset. For more information, see Visualizing Multiple Processes.

Hiding Threads From Psets

The pset command takes two thread-specific options, -hide and -unhide. These options control membership in a set of hidden threads.

Hidden threads never appear in any pset, and debugging commands are never sent to them regardless of the definition of the current set. Once hidden, those threads are represented by empty stripes in the Psets window and Where graph. By default, the set of hidden threads consists of threads 2, 3, and 4 in all ranks. These are auxiliary threads created by any program that is linked with libthread.so and are rarely interesting to a programmer.

The following procedures are valid only when debugging a multithreaded program.


procedure icon  To Hide Threads From Psets

single-step bulletType:

(prism all)pset -hide pset_expression

The Prism environment evaluates pset_expression and adds the result to the set of hidden threads.


procedure icon  To Make Hidden Threads Available to Psets Again

single-step bulletType:

(prism all)pset -unhide pset_expression

The Prism environment evaluates pset_expression and subtracts the result from the set of hidden threads.


procedure icon  To Show Currently Hidden Threads

single-step bulletType:

(prism all)pset -hide


Using Psets in Commands

As mentioned at the beginning of this chapter, you can specify pset qualifiers with several Prism commands. The following commands can take a pset as a qualifier:

  • address/
  • assign
  • call
  • catch
  • cont, contw
  • display
  • ignore
  • interrupt
  • lwps
  • next, nexti
  • print
  • pstatus
  • return, stepout
  • step, stepi
  • stop, stopi
  • sync, syncs
  • thread, threads
  • trace, tracei
  • wait
  • whatis
  • where

procedure icon  To Use a Pset Qualifier

single-step bulletType:

(prism) command options pset_qualifier [on window]

A command with a pset qualifier applies only to the processes in the set. If you omit the qualifier, the command applies to the processes in the current set.

For example, the following sets a breakpoint at line 12 for the processes in pset error:

(prism all) stop at 12 pset error

The following displays the Where graph for processes 0 through 10:

(prism all) where pset 0:10 on dedicated

See Displaying the Where Graph for a description of the Where graph.

The following creates a trace event for the members of the current pset:

(prism all) trace at 12 if x > 10

Note that this last command applies only to the members of the current pset. To apply it to all processes, use the syntax:

(prism all) trace at 12 if x > 10 pset all

Many commands cannot logically take a pset qualifier. You get an error message if you try to issue one of these commands with a pset qualifier.

Using Unbounded Psets in Commands

When running threaded programs in the Prism environment, you can encounter unbounded psets. An unbounded pset is one that contains the value of all in the thread-part of a pset specifier. The membership of such psets varies unpredictably. The term unbounded distinguishes such psets from those whose membership varies deterministically, which are referred to as variable psets (see Naming Psets).

For example:

pset 3.all

The size of such an unbounded pset is not constant, since it contains all threads created during the life of the program. The size of this set will change as threads are created and destroyed.

Pset expressions that omit specifying the thread-part imply all threads, so that pset 2 means pset 2.all, and pset all means pset all.all, both of which are unbounded sets.

If a pset expression includes one or more unbounded psets, it is also unbounded.



Note - The use of all in only the process-part of a pset specifier does not create an unbounded set. The Prism environment creates a constant number of processes at startup, taken from the number of processes you specify when you start the Prism environment with a -n (or -np) argument. For example, pset all.1 is a bounded set.



The Prism environment places several restrictions on the use of unbounded psets. You cannot use an unbounded pset as the context for an event specification or a wait every command. For an overview of information about event specifications, see Overview of Events.

In the following example, both of these uses of the wait every command are illegal:

(prism all) wait every pset all
...
(prism all) pset all
(prism all) wait every 

Similarly, you may not use unbounded sets as the context for the stop or trace commands when these commands contain actions. Examples:

(prism all) stop in foo {print x} pset all     ; illegal
(prism all) stop in foo pset all ; legal, does not contain an action

The Prism environment handles the psets that apply to the wait every, stop, and trace commands in a similar manner. When using a constant (bounded) pset, the Prism environment records the membership of the pset when the command is issued. When using an unbounded pset, the Prism environment reevaluates the pset each time the command executes. In the following example, foo is an unbounded pset.

(prism all) stop at 10 pset foo

Each time a thread executes line 10, the Prism environment reevaluates pset foo, and stops the thread if it is a member of foo.

Using Snapshots of Unbounded Psets in Commands

The Prism environment enables you to control the contents of psets derived from unbounded sets of threads. You can specify a constant membership of such a pset by capturing snapshots of the unbounded sets. You capture snapshots of unbounded sets by including the snapshot (pset_expression) argument with any command that takes a pset qualifier.

Here is an example of how the contents of unbounded psets can vary:

(prism all)pset
The current set was created by evaluating the Pset 'all' once at the time when it became the current set. The current set is defined as `all'.The set contains threads 0:3.1
(prism all)define pset all1 all - 1.1
(prism all)show pset all1
Pset 'all1' is defined as 'all - 1.1'.
The set contains the following threads: (0,2,3).1.

After running the program for a while, the membership of all and all1 both change, as shown in the following example:

(prism all)show pset all
The set contains the following threads: 0:2.(1,5,6).
(prism all)show pset all1
Pset 'all1' is defined as 'all - 1.1'.
The set contains the following threads: (0,2).(1,5,6), 1.(5,6).


procedure icon  To Create a Bounded Pset From an Unbounded Pset

single-step bulletType:

(prism all) command (pset_name) pset snapshot (expression)

In the following example, a snapshot pset, called snap1, is created. snap1 contains a subset of the threads in pset all, as defined by the snapshot expression.

(prism all)pset
The current set was created by evaluating the Pset
'all' once at the time when it became the current set.
The set contains threads: 0:2.1.
(prism all)define pset snap1 snapshot ( all - 1.1 )
(prism all)show pset snap1
Pset 'snap1' is defined as 'snapshot ( all - 1.1 )'.
The set contains the following threads: (0,2).1.

Then, after running the program for a while, the membership of (all - 1.1) and snap1 differ, as shown in this example:

(prism all)show pset all
The set contains the following threads: 0:2.(1,5,6).
(prism all)show pset snap1
Pset 'snap1' is defined as 'snapshot ( all - 1.1 )'.
The set contains the following threads: (0,2).1.

However, you can force the update of the membership of pset snap1 by issuing the eval pset command. For example,

(prism all)eval pset snap1
(prism all)show pset snap1
Pset 'snap1' is defined as 'snapshot ( all - 1.1 )'.
The set contains the following threads: (0,2).(1,5,6), 1.(5,6)

The following example shows a situation in which using an unbounded pset, all, generates an error. Note that, in a threaded program, all is equivalent to the unbounded set of all.all, which is the union of all processes and all threads. The use of the snapshot argument, however, avoids that error.

(prism all - 1.1)stop in func {print 1 } pset all
Currently, dynamic psets are not allowed in events. 
Action is dropped from event 3 because of dynamic pset all 
(3) stop in func pset all
(prism all - 1.1)stop in func {print 2 } pset snapshot(all)
(4) stop in func { print 2 } pset snapshot(all)

Referring to Nonexistent Thread Identifiers

You cannot establish a current pset that contains non-existent threads. The pset command in the following example is wrong because it specifies a thread (5) that has not been created yet.

(prism all)show pset all
The set contains the following threads: (0:3).1
(prism all)pset all.5

However, in certain contexts, such as setting breakpoints, you may use a pset qualifier containing nonexistent threads, as shown in the following example:

(prism all)stop in foo pset all.5
(prism all)


Using the Prism Environment With Sun MPI Client/Server Programs

You can use a Prism session to debug more than one Sun MPI job at a time. To debug a child or client program, it is necessary to launch an additional Prism session. If the child program is spawned using calls to MPI_Comm_spawn() or MPI_Comm_spawn_multiple(), Prism can (if enabled) debug the child program as well.

However, if an MPI job connects to another job, the current Prism session has control only of the parent or server MPI job. It cannot debug the children or clients of that job. This might occur, for example, when an MPI job sets up a client/server connection to another MPI job with MPI_Comm_accept or MPI_Comm_connect.

With the exception of programs using calls to MPI_Comm_spawn() or MPI_Comm_spawn_multiple(), to use the Prism environment to debug a Sun MPI program, the program must be written in the SPMD (single program, multiple data) style--that is, all processes that make up a Sun MPI program must be running the same executable.



Note - MPI_Comm_spawn_multiple can create multiple executables with only one job id; therefore, you can use the Prism environment to debug jobs with different executables that have been spawned with this command.




Choosing the Current File and Function

The Prism environment uses the concepts of current file and current function.

The current file is the source file currently displayed in the source window. The current function is the function or procedure displayed in the source window. You might change the current file or function if, for example, you want to set a breakpoint in a file that is not currently displayed in the source window, and you don't know the line number at which to set the breakpoint.

In addition, changing the current file and current function changes the scope used by the Prism environment for commands that refer to line numbers without specifying a file, as well as the scope used by the Prism environment in identifying variables; see How the Prism Environment Chooses the Correct Variable or Procedure for a discussion of how the Prism environment identifies variables. The scope pointer (-) in the line-number region moves to the current file or current function to indicate the beginning of the new scope.


procedure icon  To Change the Current File

single-step bulletPerform one of the following:

  • From the menu bar - Choose the File selection from the File menu. A window is displayed (shown in FIGURE 3-6), listing in alphabetical order the source files that make up the loaded program. Click on one, and it appears in the Selection box. Then click on OK and the source window updates to display the file. Or simply double-click, rapidly, on the source file. You can also edit the file name in the Selection box.


Note - The File window displays only files compiled with the -g switch.



 FIGURE 3-6 File Window

Screenshot of the File window. Buttons are OK, Cancel, and Help.
  • From the command window - Issue the file filename command. The source window updates to display the file.

procedure icon  To Change the Current Function or Procedure

single-step bulletPerform one of the following:

  • From the menu bar - Choose the Func selection from the File menu. A window is displayed, listing the functions in the program in alphabetical order. (Fortran procedure names are converted to all lowercase.) Click on one, and it appears in the Selection box. Then click on OK, and the source window updates to display the function. Or simply double-click on the function name in the list. You can also edit the function name in the Selection box.
By default, the Func window displays only functions in files compiled with the
-g switch. To display all functions in the program, click on the Select All Functions button. The button then changes to Show -g Functions; click on it to return to displaying only the -g functions.
  • From the command window - Issue the func command with the name of a function or subroutine as its argument. The source window updates to display the function.
  • From the source window - Select the name of the function in the source window by dragging the mouse over it while pressing the Shift key. When you let go of the mouse button, the source window is updated to display the definition of this function.


Note - Include only the function name, not its arguments.



Note that if the function you choose is in a different source file from the current file, changing to this function also has the effect of changing the current file.


Creating a Directory List for Source Files

If the Prism environment cannot find a file--because you moved it or for some other reason--you can explicitly add its directory to the Prism environment's search path.


procedure icon  To Add a Directory to the Search Path

single-step bulletPerform one of the following:

  • From the menu bar - Select Use from the File menu. This displays a dialog box, as shown in FIGURE 3-7. To add a directory, type its path name in the Directory box, then click on Add. To remove a directory, click on it in the directory list, then click on Remove.

 FIGURE 3-7 Use Dialog Box

Screenshot of the Use window. Buttons are Add, Remove, Close, and Help.
  • From the command window - Issue the use command on the command line. Specify a directory as an argument; the directory is added to the front of the search path. Issue use with no arguments to display the list of directories to be searched.


Note - No matter what the contents of your directory list are, the Prism environment searches for the source file first in the directory in which the program was compiled.