MP Prism provides you with the capability of viewing your message-passing program at the level of an individual process, a group of processes, or all processes that make up the program. For example, at times it may be useful to look at the status of process 0, because you have reason to believe there is a problem with it. At other times you may want to look at all processes that have encountered an error, or at all processes in which the value of a particular variable exceeds a certain number.
These groups of processes, typically chosen because they have some useful characteristic in common, are referred to as psets (pronounced "pee-sets"). MP Prism 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. For example, you can set a breakpoint that applies only to processes in a specified pset. (See " Using Psets in Commands" for more information.) In addition, many graphical actions apply only to processes in a pset.
If you don't need to view your program at the level of an individual process or a subset of processes, you can also view its operation on all the processes that make up the message-passing program.
You can view psets in the Psets window, as described in " Using the Psets Window" and " Viewing the Contents of Psets".
MP Prism assigns a logical ID number to each process that makes up a message-passing program. For example, in an 8-process message-passing program, the individual processes would be numbered 0-7. These numbers are used to identify processes in psets. Do not confuse these numbers with the Solaris process IDs (pids) assigned by the system to the message-passing processes.
As described in " Predefined Psets", Prism provides predefined psets for certain standard groups of processes; for example, the set of all processes 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 in which variable x is greater than 0. " Deleting Psets" describes how to delete psets.
If you don't specify a pset as a qualifier to a command (that can take a pset qualifier), the command is executed on the current pset; many graphical actions also apply to processes in the current set. The concept of the current pset is described in " Current Pset". " The Current Process" describes the current process, which is a distinguished process within a pset.
" The cycle Pset" describes the cycle pset, which is a predefined pset with special characteristics.
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.
To display the window:
From the menu bar - Choose the Psets selection from the Debug menu.
From the command window - Issue the command show psets on dedicated.
Figure 3-3 shows the Psets window for a 16-process message-passing program, including several user-defined psets.
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. Processes that are members of a set are shown as black (or colored) cells within a rectangle that represents the entire set of processes that make up the message-passing program.
The current process (see " The Current Process") for each pset is shown in gray (or, on a color workstation, a darker shade of the color in the other squares). The current pset (see " 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 in the upper right side of the control panel.
You can cycle through the cycle pset (see " 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, you can use the Zoom arrows to zoom in or out on these psets. The box next to 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 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 " Deleting Psets".
The File menu lets you close the Psets window.
MP Prism provides the predefined psets described below.
all - This set contains all the processes in the program; it is the default pset.
interrupted - This set contains the processes that were most recently forcibly interrupted by the user. See " Interrupting and Waiting for Processes" for a discussion of the interrupt command and a further explanation of this pset.
stopped - This set contains all processes that are currently stopped. It is the union of the sets error, interrupted, and break.
Except for the pset all, these sets are dynamic; that is, as a program executes, Prism 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. They are discussed in " Current Pset" and " The cycle Pset", respectively.
You can create psets in MP Prism. This section describes the syntax of pset creation.
This section describes the syntax you can use to specify a pset. As described below, you can assign a name to a pset you specify using this syntax; this provides a useful shorthand for complicated pset specifications.
First, to specify a pset as an argument to a command:
To apply a command to a specific pset, use the pset keyword, followed by a process specification. Put this pset clause at the end of the command line (but before an on window clause, if any). Thus,
print x pset error
prints the values of the variable x in the predefined pset error. (See " Visualizing Multiple Processes in MP Prism" for a discussion of printing variables in MP Prism.)
To specify your own pset as part of this pset clause:
Specify an individual process number. An individual process can constitute a pset. Thus,
print x pset 0
prints the value of x in process 0.
Specify the name of a pset. Name a pset using the define pset command, as described in the section "Naming Psets," below. Thus,
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. Thus,
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. Thus,
print x pset 0:10
prints x in processes 0 through 10. And
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. For example,
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 ||. For example,
print x pset 0:2 + 8:10
prints x in processes 0, 1, 2, 8, 9, and 10.
print x pset foo | bar
prints x in processes that are members of either pset foo or pset bar.
Prism evaluates the pset expression from left to right. If a process returns true for the first part of the expression, it is not evaluated further. In the above example, if a process is a member of foo, its value of x is printed; Prism does not check its membership in bar.
Use a minus sign to specify the difference of two psets. For example,
print x pset stopped - foo
prints x in all processes that are stopped except those belonging to the pset foo.
To specify the intersection of two psets, use the &, &&, or * symbol. For example,
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 above example, if a process is not a member of foo, Prism doesn't bother checking its membership in bar; it won't be printed in any case.
Prism must evaluate a pset expression in each process at the time the command is executed; the processes must be stopped for Prism to do this. The evaluation fails if any of the processes being evaluated are running. Using the predefined pset stopped on the left of an intersection expression is a useful way of ensuring that a command applies only to stopped processes.
Thus,
print x pset stopped & foo
prints x only in the members of foo that are stopped.
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.
Thus,
print x pset { y > 1 }
prints x in processes where y is greater than 1. And
print x pset all - { y == 1 }
prints x in all processes except those in which y is equal to 1.
Membership in a set defined with this syntax can change based on the current state of your program; such a pset is referred to as variable. See " Evaluating 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 isn't 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:
print x pset stopped && {isactive(x)}
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 to specify the pset. You can use any name except the names that Prism pre-defines; see " Predefined Psets". The name must begin with a letter; it can contain any alphanumeric character, plus the dollar sign ($) and underscore (_).
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.
For example,
define pset odd 1:31:2
creates a pset called odd containing the odd-numbered processes between 1 and 31.
define pset xon { x .NE. 0 }
defines a pset consisting of those processes in which x is not equal to 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. For example,
define pset xon { isactive(x) && (x .NE. 0) }
Both versions create a variable pset whose contents will change based on the value of x. See below for more discussion of variable psets. Finally, note that all processes must be stopped for this syntax to work. To ensure that the definition applies only to stopped processes, use this syntax:
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 the Contents of Psets" for more information about show psets.
Prism evaluates the membership of a variable pset when it is defined. If no processes meet the condition (for example, because the program is not active), Prism prints appropriate error messages, but the set is defined.
Subsequently, you can re-evaluate the membership of the pset by issuing the eval pset command, specifying the name of the pset as its argument. For example,
eval pset xon
evaluates the membership of the pset xon. This causes the display for the pset to be updated in the Psets window.
Note that this evaluation will fail if:
Processes are running that need to be polled in evaluating the pset; or
The pset's definition contains a variable that is not active in any of the processes being polled
For example, if you issue this command:
define pset foo { x > 0 }
you must make sure that all processes are stopped, and x is active on all processes, when you issue the command
eval pset foo
To ensure that the evaluation succeeds, you would need to use the more complicated syntax described above:
define pset foo stopped && { isactive(x) && (x > 0) }
This 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 (MP Prism Only)".
Note the difference between dynamic and variable psets. The membership in both can change as a program executes. Dynamic psets are predefined sets like stopped and interrupted; Prism automatically updates their membership as the program executes. Variable psets are defined by the user, and the user must explicitly update their membership by issuing the eval pset command.
This section describes the methods you use to display psets in MP Prism.
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.
To display a pset, 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. Click on a set name, and that set is displayed in the window.
To hide a pset, choose the Hide selection from the Options menu. Once again, this displays the list of predefined and user-defined psets. 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 there are choices All Sets and all in the Show and Hide submenus. The All Sets choice refers to all psets; the all choice refers to the predefined pset all.
If you have too many psets to be shown in the display window of the Psets window, the navigator rectangle to the right of the Cycle arrows lets you pan through the psets. The white box in the rectangle shows the position of the display area relative to all the psets that are to be displayed:
You can 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 reduces the size of the boxes representing the psets. Clicking on the Zoom down arrow increases the size of these boxes. By default, the boxes are at their highest zoom setting.
Use the show pset command to print the contents of the pset you specify. For example, the command
show pset stopped
might produce this response:
The set contains the following processes: 0:3.
The show pset command is discussed further in " Finding Out the Current Pset".
The show psets command displays the contents and status of all psets.
(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
You can delete named psets that you have defined. You cannot delete any predefined pset except cycle; see " The cycle Pset". To delete a pset:
From the Psets window - Choose the Delete selection 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,
delete pset xon
deletes the pset named xon.
See " Events Taking Pset Qualifiers (MP Prism Only)" for a discussion of the effect of deleting a pset on events that have been defined to affect the members of that set.
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 Prism. In addition, many graphical actions in MP Prism apply only to the members of the current set.
When a program is first loaded, the current pset is the default pset, all.
You can change the current pset via the Psets window or from the command line.
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).
Choose the Set Pset selection 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 at the top right of the Psets window, 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.
pset foo
changes the current pset to foo.
You can also use the pset command with the pset-specification syntax described in " Defining Psets". For example,
pset 0:15:3
You cannot change the current pset to one that has no members. If you try to do so, nothing happens in the Psets window, and you get a message like this one in the history region of the command window:
Cannot set current pset to running -- it is empty.
MP Prism provides many ways of finding out the current pset:
As described in the previous section, the name of the current pset appears in the Current Set box at the top right of the Psets window.
The name of the current pset appears in the status region in MP Prism's main window.
The (prism) prompt on the command line and in commands-only MP Prism identifies the current pset. For example, Prism's response to the pset command in the previous section would look like this:
(prism all) pset foo (prism foo)
In giving examples of MP Prism commands, the (prism) prompt is used only when necessary to show the effect of a command.
To list the processes in the current pset, issue the show pset command without arguments:
(prism foo) show pset pset 'current' is defined as 'foo'. The set contains the following processes: 1,2.
The Psets window also displays the processes in the current pset.
" Predefined Psets" described dynamic psets--predefined sets like running, stopped, and interrupted, whose contents Prism automatically updates during the execution of the program.
If you choose a dynamic pset to be the current pset, you create a static pset that consists of the processes that are members of the dynamic set at the time you issue the pset command (or otherwise choose it to be the current set). To make this clear, the (prism) prompt changes to list the processes that are members of this static set. For example, if processes 0, 1, and 13 are the only processes that are stopped, the pset command has this effect:
(prism all) pset stopped (prism 0:1, 13)
Output of the show pset command is explicit under these circumstances:
(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.
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. For example, this command shortens the prompt long_pset_name to long_pset:
(prism long_pset_name) set $prompt_length=9 (prism long_pset)
" Defining Psets" describes how to create variable psets--user-defined psets whose membership can change in the course of program execution. You use the eval pset command to update the membership of a variable 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. If you have not executed an eval pset command to update the set's membership, the membership continues to be what it was when you created the set.
Each pset has a current process. The current process has a variety of uses in MP Prism:
The source window displays the source code executing in the current process of the current pset.
The Where graph centers around the call stack of the current pset's current process; see " Where Graph".
The current process determines the scope used in interpreting the names of variables; see " Scope in MP Prism".
By default, the current process is the lowest-numbered process in the set. You can change this as described below.
From the Psets window - Use one of these methods to change the current process via the Psets window:
Click on the cell representing the process in the displayed pset. The cell turns a darker shade of the color for the other processes (or, on a non-color workstation, gray).
To change the current process in the current pset, you can also edit the number in the box under Process at the top right of the window, then press Return.
From the command line - Issue the process command to specify another current process for the current pset. For example,
(prism all) process 2 The current process is now 2.
Issue the process command without any arguments to print the current process of the current pset.
When you change a current process, by any of the methods described above, the pset keeps this new current process until you explicitly change it. That is, if you switch to a different current set, then switch back to the original set, the original set will still have the same current process.
In debugging a message-passing program, you may often want to look in turn at each process within a pset--for example, to see what the problem is for each process in the error pset. The cycle pset provides you with a convenient way of doing this.
You create a cycle pset out of an existing pset. If the existing pset 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. You can set it to some other pset via the define pset command, as described in " Defining Psets". For example,
(prism all) define pset cycle foo
copies foo into the cycle pset.
You can cycle through the processes in the cycle pset as follows:
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.
Clicking on a Cycle arrow does this:
It advances the current process in the cycle pset to be the next member in the set.
It makes the current pset consist of only this process.
From the command line - Use the cycle command. This has the same effect as clicking on the right cycle arrow in the Psets window. For 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)
Note that changing the cycle pset erases any previous cycling information. For example, if you do the following:
Make foo the current set and cycle partway through it.
Make bar the current set.
Once again make foo the current set.
Then you start at the beginning again when you cycle through the members of foo.
From the source-window pop-up menu - Choose Cycle from this menu to advance to the next member of the cycle pset.
MP Prism 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 in MP Prism".
As mentioned at the beginning of "Using Psets in MP Prism", some commands can take a pset as a qualifier; they are listed at the end of this section. Put this qualifier after any arguments to the command, but before the optional on window syntax that specifies the window in which output is to be displayed. 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.
Thus,
stop at 12 pset error
sets a breakpoint at line 12 for the processes in pset error.
where pset 0:10 on dedicated
displays the Where graph for processes 0 through 10. See " Where Graph" for a description of the Where graph.
trace at 12 if x > 10
creates a trace event for the members of the current pset.
Note that this last command applies only to the members of the current pset. To apply it to all processes, use the syntax
trace at 12 if x > 10 pset all
Many commands, of course, cannot logically take a pset qualifier. You get an error message if you try to issue one of these commands with a pset qualifier.
Here are the Prism commands that can take a pset qualifier:
address/ assign call catch cont, contw display ignore interrupt next, nexti print pstatus return step, stepi stop, stopi trace, tracei wait whatis where