This section describes how to name a single thread, how to group threads and processes into sets, and how to apply PGDBG commands to groups of processes and threads.
PGDBG can operate in four debug modes. As a convenience the mode determines a short form for uniquely naming threads and processes. The debug mode is set automatically or by using the pgienv command.
Debug Mode |
Program Characterization |
Serial |
A single thread of execution |
Threads-only |
A single process, multiple threads of execution |
Process-only |
Multiple processes, each process made up of a single thread of execution |
Multilevel |
Multiple processes, at least one process employing multiple threads of execution |
PGDBG starts out in serial mode reflecting a single thread of execution. Thread IDs can be ignored in serial debug mode since there is but a single thread of execution.
Enter threads-only mode to debug a program with a single SMP process. As a convenience the process ID portion can be omitted. PGDBG automatically enters threads-only debug mode from serial debug mode when it attaches to SMP threads.
1 |
Thread 1 of all processes (*.1) |
* |
All threads of all processes (*.*) |
0.7 |
Thread 7 of process 0 (Multilevel thread names valid in threads-only debug mode) |
In threads-only debug mode status and error messages are prefixed with thread IDs depending on context.
Enter process-only mode to debug a program with non-SMP nodes. As a convenience the thread ID portion can be omitted. PGDBG automatically enters process-only debug mode from serial debug mode when the target program returns from MPI_Init.
0 |
All threads of process 0 (0.*) |
* |
All threads of all processes (*.*) |
1.0 |
Thread 0 of process 1 (Multilevel thread names are valid in this mode) |
In process-only debug mode status and error messages are prefixed with process IDs depending on context.
The name of a thread in multilevel debug mode is the thread ID prefixed with its parent process ID. This forms a unique name for each thread across all processes. This naming scheme is valid in all debug modes. PGDBG changes automatically to multilevel debug mode from process-only debug mode or threads only-debug mode when at least one MPI process spawns SMP threads.
0.1 |
Thread 1 of process 0 |
0.* |
All threads of process 0 |
In multilevel debug, mode status and error messages are prefixed with process/thread IDs depending on context.
If PGDBG is licensed as a Workstation product, it operates in Threads-only mode by default (however multilevel notation is always valid).
If PGDBG is licensed as a CDK product, it operates in process-only mode by default.
The PGDBG prompt displays the current thread according to the current debug mode. See The PGDBG Command Prompt for a description of the PGDBG prompt.
The pgienv command is used to change debug modes manually.
pgienv mode [serial|thread|process|multilevel]
The debug mode can be changed at any time during a debug session.
A process/thread set (p/t-set) is used to restrict a debugger command to apply to just a particular set of threads. A p/t-set is a set of threads drawn from all threads of all processes in the target program. Use p/t-set notation (described below) to define a p/t-set.
The current p/t-set can be set using the focus command, which establishes the default p/t-set for cases where no p/t-set prefix is specified. This begins as the debugger-defined set [all], which describes all threads of all processes.
P/t-set notation can be used to prefix a debugger command. This overrides the current p/t-set defining the target threads to be those threads described by the prefix p/t-set.
The target p/t-set is defined then to be the prefix p/t-set if present, the current p/t-set otherwise. Use defset to define a named or user-defined p/t-set. Use viewset and whichsets to inspect the active members described by a particular p/t-set. The target p/t-set determines which threads are affected by a PGDBG command.
The following set of rules describes how to use and construct process/thread sets (p/t-sets).
simple command : [p/t-set-prefix] command parm0, parm1, ... compound command : [p/t-set-prefix] simple-command [; simple-command ...] p/t-id : {integer|*}.{integer|*}
Optional notation when processes-only debugging or threads-only debugging is in effect (see pgienv command).
{integer|*}
p/t-range : p/t-id:p/t-id p/t-list : {p/t-id|p/t-range} [, {p/t-id|p/t-range} ...] p/t set : [[!]{p/t-list|set-name}]
[0,4:6] |
Threads 0,4,5, and 6 of all processes |
[*] |
All threads of all processes |
[*.1] |
Thread 1 of all processes. Multilevel notation is valid in threads-only mode |
[*.*] |
All threads of all processes |
[0,2:3] |
All threads of process 0, 2, and 3 (equivalent to [0.*,2:3.*]) |
[*] |
All threads of all processes (equivalent to [*.*]) |
[0] |
All threads of process 0 (equivalent to [0.*]) |
[*.0] |
Thread 0 of all processes. Multilevel syntax is valid in process-only mode. |
[0:2.*] |
All threads of process 0, 1, and 2. Multilevel syntax is valid in process-only debug mode. |
[0.1,0.3,0.5] |
Thread 1,3, and 5 of process 0 |
[0.*] |
All threads of process 0 |
[1.1:3] |
Thread 1,2, and 3 of process 1 |
[1:2.1] |
Thread 1 of processes 1 and 2 |
[clients] |
All threads defined by named set clients |
[1] |
Incomplete; invalid in multilevel debug mode |
P/t-sets defined with defset are not mode dependent and are valid in any debug mode.
The members of a dynamic p/t-set are those active threads described by the p/t-set at the time that p/t-set is used. A p/t-set is dynamic by default. Threads and processes are created and destroyed as the target program runs. Membership in a dynamic set varies as the target program runs.
defset clients [*.1:3] |
Defines a named set clients whose members are threads 1, 2, and 3 of all processes that are currently active when clients is used. Membership in clients changes as processes are created and destroyed. |
The members of a static p/t-set are those threads described by the p/t-set at the time that p/t-set is defined. Use a ! to specify a static set. Membership in a static set is fixed at definition time.
defset clients [!*.1:3] |
Defines a named set clients whose members are threads 1, 2, and 3 of those processes that are currently active at the time of the definition. |
The current p/t-set is set by the focus command. The current p/t-set is described by the debugger prompt (depending on debug mode). A p/t-set can be used to prefix a command to override the current p/t-set. The prefix p/t-set becomes the target p/t-set for the command. The target p/t-set defines the set of threads that will be affected by a command. See The PGDBG Command Prompt for a description of the PGDBG prompt.
Example: The target p/t-set is the current p/t-set:
pgdbg [all] 0.0> cont Continue all threads in all processes
Example: The target p/t-set is the prefix p/t-set:
pgdbg [all] 0.0> [0.1:2] cont Continue threads 1 and 2 of process 0 only
Above, the current p/t-set is the debugger-defined set [all] in both cases. In the first case [all] is the target p/t-set. In the second case the prefix set overrides [all] as the target p/t-set. The continue command is applied to all active threads in the target p/t-set. Using a prefix p/t-set does not change the current p/t-set.
The following commands are new to PGDBG. Their function is to collect threads into logical groups. defset and undefset can be used to manage a list of named p/t-sets. focus is used to set the current p/t-set. viewset is used to view the active members described by a particular p/t-set. whichsets is used to describe which p/t-sets a particular process/thread belongs to.
Command |
Description |
focus |
Set the target process/thread set for commands. Subsequent commands will be applied to the members of this set by default |
defset |
Assign a name to a process/thread set. Define a named set. This set can later be referred to by name. A list of named sets is stored by PGDBG |
undefset |
'Undefine' a previously defined process/thread set. The set is removed from the list. The debugger-defined p/t-set [all] can not be removed |
viewset |
List the members of a process/thread set that currently exist as active threads |
whichsets |
List all defined p/t-sets to which the members of a process/thread set belongs |
Example:
Breakpoint at 0x8048fd0, function main, file omp.c, line 5 #5: printf("One thread ... \n"); pgdbg> pgienv mode thread Entering threads-only debug mode. pgdbg [all] 0> defset initial [0] "initial" [0] : [0] pgdbg [all] 0> focus [initial] [initial] : [0] [0] pgdbg [initial] 0> n One thread ... [0] Stopped at 0x8048fe0, function main, file omp.c, line 7 #7: #pragma omp parallel ([*] Process Stopped) pgdbg [initial] 0> n ([*] Entering Parallel Region) Warning: OMP_NUM_THREADS greater than available cpus (set to 4; cpus = 1) ([1] New Thread) ([2] New Thread) ([3] New Thread) [2] Stopped at 0x8048ffe, function main, file omp.c, line 11 #11: myid = omp_get_thread_num(); [0] Stopped at 0x8048ffe, function main, file omp.c, line 11 #11: myid = omp_get_thread_num(); [3] Stopped at 0x8048ffe, function main, file omp.c, line 11 #11: myid = omp_get_thread_num(); [1] Stopped at 0x8048ffe, function main, file omp.c, line 11 #11: myid = omp_get_thread_num(); ([*] Process Stopped) pgdbg [initial] 0> threads 0 ID PID STATE SIGNAL LOCATION => 0 10627 Stopped SIGTRAP main line: 11 in "omp.c" address: 0x8048ffe 1 10629 Stopped SIGTRAP main line: 11 in "omp.c" address: 0x8048ffe 2 10630 Stopped SIGTRAP main line: 11 in "omp.c" address: 0x8048ffe 3 10631 Stopped SIGTRAP main line: 11 in "omp.c" address: 0x8048ffe pgdbg [initial] 0> n [0] Stopped at 0x8049007, function main, file omp.c, line 13 #13: for(i=0;i<2;i++){ ([*] Process Stopped) pgdbg [initial] 0> threads 0 ID PID STATE SIGNAL LOCATION => 0 10627 Stopped SIGTRAP main line: 13 in "omp.c" address: 0x8049007 1 10629 Stopped SIGTRAP main line: 11 in "omp.c" address: 0x8048ffe 2 10630 Stopped SIGTRAP main line: 11 in "omp.c" address: 0x8048ffe 3 10631 Stopped SIGTRAP main line: 11 in "omp.c" address: 0x8048ffe pgdbg [initial] 0> whichsets [initial] Thread 0 belongs to: all initial pgdbg [initial] 0> viewset "all" [*.*] : [0.0,0.1,0.2,0.3] "initial" [0] : [0] pgdbg [initial] 0> focus [all] [all] : [0.0,0.1,0.2,0.3] [*.*] pgdbg [all] 0> undefset initial p/t-set name "initial" deleted. pgdbg [all] 0>
The p/t-set initial is defined to contain only thread 0. We focus on initial and advance the thread. Focus sets the current p/t-set. Because we are not using a prefix p/t-set, the target p/t-set is the current p/t-set which is initial. When the thread enters a parallel region all non-initial threads inherit the execution goal of the initial thread and they too are advanced into the parallel region. However once inside the parallel region only thread 0 is advanced since the target p/t-set contains only that thread. The whichsets command above shows us that thread 0 is a member of two defined p/t-sets. The viewset command displays all threads that are active and are members of defined p/t-sets. We enter 'pgienv mode thread' to demonstrate entering threads-only debug mode, however this is unnecessary since PGDBG would automatically switch to threads-only debug mode upon entering the parallel region. We also demonstrate the 'pgienv verbose' command which turns verbose messaging on, displaying the stop location of each thread as it stops.
The PGDBG command set is divided into three disjoint subsets according to how each command reacts to the current p/t-set. Process level and thread level commands are parallelized. Global commands are not.
Process Level Commands |
Parallel by current p/t-set or prefix p/t-set |
Thread Level Commands |
Parallel by prefix p/t-set. Ignores current p/t-set |
Global Commands |
Non-parallel commands |
The process level commands are the PGDBG control commands.
The PGDBG control commands apply to the active members of the current p/t-set by default. A prefix set can be used to override the current p/t-set. The target p/t-set is the prefix p/t-set if present, the current p/t-set otherwise.
cont next nexti step stepi
stepout sync synci halt wait
Example:
pgdbg [all] 0.0> focus [0.1:2] pgdbg [0.1:2] 0.0> next
The next command is applied to threads 1 and 2 of process 0.
Example:
pgdbg [clients] 0.0> [0.3] n
This demonstrates the use of a prefix p/t-set. The next command is applied to thread 3 of process 0 only.
The following commands are not concerned with the current p/t-set. When no p/t-set prefix is used, these commands execute in the context of the current thread of the current process by default. That is, thread level commands ignore the current p/t-set. Thread level commands can be applied to multiple threads by using a prefix p/t-set. When a prefix p/t-set is used, the commands in this section are executed in the context of each active thread described by the prefix p/t-set. The target p/t-set is the prefix p/t-set if present, or the current thread otherwise. The thread level commands are:
Set assign pc sp fp retaddr regs line func lines addr entry decl whatis rval lval sizeof iread cread sread fread dread print hex dec oct bin ascii string disasm dump pf noprint where stack break* stackdump scope watch track break do watchi tracki doi hwatch hwatchread hwatchboth
* breakpoints and variants: (stop, stopi, break, breaki) if no prefix p/t-set is specified, [all] is used (overriding current p/t-set).
When a prefix p/t-set is used, the threads described by the prefix are sorted per process by thread ID in increasing order, the processes are sorted by process ID in increasing order, and duplicates are removed. The command is then applied to the threads in the resulting list in order.
Example:
pgdbg [all] 0.0> list #33: #34: gethostname(hname,len); #35: #36: MPI_Comm_rank(MPI_COMM_WORLD,&myrank); #37: #38:==>> fprintf(stderr,"Host %s, Rank %d, Time %d.\n",hname,myrank,aft-bef); #39: #40: switch (myrank){ #41: #42: case 0: pgdbg [all] 0.0> procs ID IPID STATE THREADS HOST => 0 29726 Stopped 3 red1 1 10778 Stopped 1 red2 2 29743 Stopped 3 red1 3 10791 Stopped 3 red2 pgdbg [all] 0.0> print myrank 0 pgdbg [all] 0.0> [2:3.*,1:2.*] print myrank [1.0] print myrank: 1 [2.0] print myrank: 2 [2.1] print myrank: 2 [2.2] print myrank: 2 [3.0] print myrank: 3 [3.2] print myrank: 3 [3.1] print myrank: 3 pgdbg [all] 0.0>
In this example myrank is filled by a call to MPI_Comm_rank on each of the 4 processes. Without a prefix p/t-set, the print command executes in the context of the current thread of the current process, printing rank 0. The thread members of the prefix p/t-set are sorted and duplicates are removed. The print command iterates over the resulting list.
The rest of the PGDBG commands ignore threads and processes, or are defined globally for all threads across all processes. The current p/t-set and a prefix p/t-set are ignored.
Here is a sample of those commands that are defined globally.
Debug run rerun threads procs proc thread call unbreak delete disable enable arrive wait breaks status help script log shell alias unalias directory repeat pgienv files funcs source use cd pwd whereis edit / ? history catch ignore quit focus defset undefset viewset whichsets display...
PGDBG supports thread and process control (`stepping', `nexting', 'continuing' ...) everywhere in the program. Threads and processes can be advanced in groups anywhere in the program.
The PGDBG control commands are:
cont, step, stepi, next, nexti, stepout, halt, wait, sync, synci
halt |
Halt running process/thread |
sync, synci |
Advance process/thread to specific program location, ignoring user defined events that fire |
wait |
Return PGDBG prompt only after specific processes/threads stop. |
Set the current p/t-set, or use a prefix p/t-set, to describe those threads you wish to advance, or use a prefix p/t-set.
A thread inherits the control operation of the current thread when it is created. So if the current thread 'next's over an _mp_init call (at the beginning of every OpenMP parallel region), then all threads created by _mp_init will 'next' into the parallel region.
A process inherits the control operation of the current process when it is created. So if the current process is 'continuing' out of a call to MPI_Init, the new process will do the same.
The PGDBG GUI supports process/thread selection via the use of the thread grid and the process grid. To change the current process/thread just click on the corresponding button in the grid. Changing processes updates the thread grid (if present) to display the threads of the new current process.
Accompanying each grid is a set of toggle buttons with the labels `all' or `current'. These buttons can be used to construct a prefix p/t-set for the next command. The toggle buttons apply to the 'cont', 'stepout', 'next', 'nexti', 'step', 'stepi', 'halt', and 'wait' buttons only.
A process grid is part of the GUI if PGDBG is licensed as part of the CDK. Selecting `all' processes will translate to a `*' for processes in the prefix set. Selecting `current' will place the process ID of the current process into the prefix set.
A thread grid is part of the GUI if PGDBG is licensed as part of the CDK or as part of the Workstation. Selecting `all' threads will translate to a `*' for threads in the prefix set. Selecting `current' will place the thread ID of the current thread into the prefix set.
Example:
`all' process and `all' threads constructs a [*.*] p/t-set prefix. `current' process and `all' threads constructs a [0.*] p/-set prefix if process 0 is the current process for example.
At most one of the grids will also have a `none' button in the toggle set. Selecting none disables automatic p/t-set prefixing by the GUI in effect causing the target p/t-set to be the current p/t-set (since there is no prefix override).
PGDBG allows you to configure how threads and processes stop in relation to one another. PGDBG defines two new pgienv environment variables, threadstop and procstop, for this purpose. PGDBG defines two stop modes, synchronous (sync) and asynchronous (async).
sync |
Synchronous stop mode; when one thread stops at a breakpoint (event), all other threads are stopped soon after |
async |
Asynchronous stop mode; each thread runs independently of the other threads. One thread stopping does not affect the behavior of another |
Thread stop mode is set using the pgienv command as follows:
pgienv threadstop [sync|async]
Process stop mode is set using the pgienv command as follows:
pgienv procstop [sync|async]
PGDBG defines the default to be asynchronous for both thread and process stop modes. When debugging an OpenMP program, PGDBG automatically enters synchronous thread stop mode in serial regions, and asynchronous thread stop mode in parallel regions. Synchronous stopping is useful for debugging critical regions. See OpenMP Debugging for details.
The pgienv environment variable threadstopconfig and procstopconfig can be set to automatic (auto) or user defined (user) to enable or disable this behavior.
pgienv threadstopconfig [auto|user] pgienv procstopconfig [auto|user]
Selecting user defined stop mode prevents the debugger from changing stop modes automatically. Automatic stop configuration is the default for both threads and processes.
Example: Leaving a parallel region (synchronous thread stop mode)
pgdbg [all] 0> pgienv threadstopconfig auto Entering user defined thread stop mode. pgdbg [all] 0> [*.*] next ([*] Entering Serial Region) [0] Stopped at 0x804904f, function main, file omp.c, line 19 #19: printf("... back to one thread.\n"); pgdbg [all] 0> threads 0 ID PID STATE SIGNAL LOCATION => 0 10706 Stopped SIGTRAP main line: 19 in "omp.c" address: 0x804904f 1 10708 Stopped SIGSTOP sched_yield address: 0x804b0e1 2 10709 Stopped SIGSTOP _mp_barrier address: 0x80491c4 3 10710 Stopped SIGSTOP _mp_barrier address: 0x8049194
Threads 1,2,3 are stopped when 0 hits line 19 (serial region) in synchronous thread stop mode. The debugger enters synchronous thread stop mode automatically since threadstopconfig is set to auto (which is the default).
Example: Leaving a parallel region (asynchronous thread stop mode)
pgdbg [all] 0> pgienv threadstopconfig user Entering user defined thread stop mode. pgdbg [all] 0> pgienv threadstop async Threads will stop asynchronously. pgdbg [all] 0> n ([*] Entering Serial Region) [0] Stopped at 0x804904f, function main, file omp.c, line 19 #19: printf("... back to one thread.\n"); pgdbg [all] 0> threads 0 ID PID STATE SIGNAL LOCATION => 0 10713 Stopped SIGTRAP main line: 19 in "omp.c" address: 0x804904f 1 10715 Running 2 10716 Running 3 10717 Running pgdbg [all] 0> halt [0] ERROR: Thread Stopped. Ignoring halt. pgdbg [all] 0> threads 0 ID PID STATE SIGNAL LOCATION => 0 10713 Stopped SIGTRAP main line: 19 in "omp.c" address: 0x804904f 1 10715 Stopped SIGSTOP _mp_barrier address: 0x80491a0 2 10716 Stopped SIGSTOP _mp_barrier address: 0x8049179 3 10717 Stopped SIGSTOP _mp_barrier address: 0x8049194
Threads 1,2,3 are left running when 0 hits line 36 (serial region) in asynchronous thread stop mode. Threads 1,2,3 can be halted using the halt command. If we did not set threadstopconfig to user, then when the program enters a serial region, the debugger would automatically select sync thread stop mode as in the previous example.
Wait mode describes when PGDBG will accept the next command. The wait mode is defined in terms of the execution state of the program. Wait mode describes to the debugger which threads/processes must be stopped before it will accept the next command. In certain situations it is desirable to be able to enter commands while the program is running and not stopped. The PGDBG prompt will not appear until all processes/threads are stopped. However, a prompt may be available before all processes/threads have stopped. Pressing <enter> at the command line will bring up a prompt if it is available. The availability of the prompt is determined by the current wait mode and any pending wait commands (described below).
PGDBG accepts a compound statement at each prompt. Each compound statement is a bundle of commands, which are processed in order at once. The wait mode describes when to accept the next compound statement.
PGDBG supports three wait modes:
any |
The prompt is available only after at least one thread has stopped since the last control command |
all |
The prompt is available only after all threads have stopped since the last control command |
none |
The prompt is available immediately after a control command is issued |
Thread wait mode describes which threads PGDBG waits for before accepting a next command.
Process wait mode describes which processes PGDBG waits for before accepting a next command.
Thread wait mode is set using the pgienv command as follows:
pgienv threadwait [any|all|none]
Process wait mode is set using the pgienv command as follows:
pgienv procwait [any|all|none]
If process wait mode is set to none, then thread wait mode is ignored.
In TEXT mode PGDBG defaults to
threadwait all procwait any
If the target program goes MPI parallel then procwait is changed to none automatically by PGDBG.
In GUI mode
threadwait none procwait none
Setting the wait mode may be necessary when invoking the debugger using the -s (script file) option in GUI mode (to ensure that the necessary threads are stopped before the next command is processed if necessary).
PGDBG also provides a wait command which can be used to insert explicit wait points in a command stream. Wait uses the target p/t-set by default, which can be set to wait for any combination of processes/threads. The wait command can be used to insert wait points between the commands of a compound statement.
pgdbg [all] 0> help wait [wait] Wait for running threads to stop before next prompt. The 'wait' command is applied to all active threads in the target p/t-set. wait - Wait for running threads in target p/t-set to stop using default wait mode (set using the pgienv command). wait any - Wait for *any* running threads in target p/t-set to stop. wait all - Wait for *all* running threads in target p/t-set to stop.
The threadwait and procwait environment variables can be used to configure the behavior of wait (see pgienv).
Let S be the target p/t-set. Let P be the set of all processes described by S. Let p be a process. Let T be the set of all threads described by S. Let t be a thread. The following table describes the behavior of wait:
Command |
threadwait |
procwait |
Wait set |
wait |
all |
all |
Wait for T |
wait |
all |
none|any |
Wait for all threads in at least one p in P |
wait |
none|any |
all |
Wait for T |
wait |
none|any |
none|any |
Wait for all t in T for at least one p in P |
wait any |
all |
all |
Wait for at least one thread for each process p in P |
wait any |
all |
none|any |
Wait for at least one t in T |
wait any |
none|any |
all |
Wait for at least one thread in T for each process p in P |
wait any |
none|any |
none|any |
Wait for at least one t in T |
wait all |
all |
all |
Wait for T |
wait all |
all |
none|any |
Wait for all threads of at least one p in P |
wait all |
none|any |
all |
Wait for T |
wait all |
none|any |
none|any |
Wait for all t in T for at least one p in P |
Wait none |
all|none| any |
all|none|any |
Wait for no threads |
Use the pgienv command to enable/disable various status messages. This can be useful in text mode in the absence of the graphical aids provided by the GUI.
pgienv verbose <bitmask>
Choose the debug status messages that are reported by PGDBG. Accepts an integer valued bit mask of the following values:
0x1 |
Standard |
Report status information on current process/thread only. A message is printed when the current thread stops only. Also report when threads and processes are created and destroyed. Standard messaging cannot be disabled. (default) |
0x2 |
Thread |
Report status information on all threads of (current) processes. A message is reported each time a thread stops. If Process messaging is also enabled, then a message is reported for each thread across all processes. Otherwise messages are reported for threads of the current process only. |
0x4 |
Process |
Report status information on all processes. A message is reported each time a process stops. If Thread messaging is also enabled, then a message is reported for each thread across all processes. Otherwise messages are reported for the current thread only of each process. |
0x8 |
SMP |
Report SMP events. A message is printed when a process enters/exits a parallel region, or when the threads synchronize. |
0x16 |
Parallel |
Report process-parallel events (default). Currently unused. |
0x32 |
Symbolic debug information |
Report any errors encountered while processing symbolic debug information (e.g. STABS, DWARF). |
Example:
pgdbg> pgienv verbose -1 pgdbg> [0,2] b 15 breakpoint set at: main line: 15 in "omp.c" address: 0x804903a 1 pgdbg> [1,3] b 13 breakpoint set at: main line: 13 in "omp.c" address: 0x8049007 2 pgdbg [all] 0> list 6,20 #6: #7: #pragma omp parallel #8: { #9: int myid,i; #10: #11: myid = omp_get_thread_num(); #12: #13: for(i=0;i<2;i++){ #14: printf("HELLO %d, %d\n",getpid(),omp_get_thread_num()); #15: } #16: #17: } #18: #19: printf("... back to one thread.\n"); #20: pgdbg> c ./omp loaded by ld-linux.so.2. libpgthread.so loaded by ld-linux.so.2. libm.so.6 loaded by ld-linux.so.2. libc.so.6 loaded by ld-linux.so.2. ld-linux.so.2 loaded by ld-linux.so.2. One thread ... (Entering Parallel Region) Warning: OMP_NUM_THREADS greater than available cpus (set to 4; cpus = 1) ([1] New Thread) ([2] New Thread) ([3] New Thread) HELLO 10816, 0 [3] Breakpoint at 0x8049007, function main, file omp.c, line 13 #13: for(i=0;i<2;i++){ [1] Breakpoint at 0x8049007, function main, file omp.c, line 13 #13: for(i=0;i<2;i++){ [0] Breakpoint at 0x804903a, function main, file omp.c, line 15 #15: } HELLO 10819, 2 [2] Breakpoint at 0x804903a, function main, file omp.c, line 15 #15: } ([*] Process Stopped) pgdbg [all] 0>
Verbose messaging is turned on. A description is printed each time a thread stops at an event. The thread's ID prefixes each message. A message is printed as the program goes thread-parallel, and a message is printed to indicate that all threads have stopped.