Using GDB I can't seem to print the value of shared variables within OpenMP threads. For example, using the following program:
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int priv, tid, pub = 100;
#pragma omp parallel private(priv, tid) num_threads(2)
{
tid = omp_get_thread_num();
priv = tid * 10;
#pragma omp sections
{
#pragma omp section
{
printf("SECTION 0: tid=%d, priv=%d, pub=%d\n", tid, priv, pub);
}
#pragma omp section
{
printf("SECTION 1: tid=%d, priv=%d, pub=%d\n", tid, priv, pub);
}
}
}
return EXIT_SUCCESS;
}
In GDB, if I break at line 15 (the printf of section 0), and I try to print the value of "pub", I get the «No symbol "pub" in current context.» message:
Breakpoint 1, main._omp_fn.0 () at omp_simplesec.c:15
15 printf("SECTION 0: tid=%d, priv=%d, pub=%d\n", tid, priv, pub);
(gdb) print pub
No symbol "pub" in current context.
I am compiling with GCC, and tried different debugging flags (-g3 -ggdb3 -gstabs3 -gstabs+3), without success. I also tried disabling all optimizations with -O0, again with no success. However, I can see the value of private variables by using the -gstabs+ flag.
Thanks in advance.
OpenMP in GCC is implemented using outlining. It means that the code for each parallel region is extracted in its own function. For example:
int main(int argc, char *argv[]) {
int priv, pub = 100;
#pragma omp parallel private(priv) num_threads(2)
{
printf("priv = %d, pub = %d\n", priv, pub);
}
return EXIT_SUCCESS;
}
gets transformed into:
strict .omp_data_s {
int pub;
};
void main._omp_fn.0(struct .omp_data_s* .omp_data_i) {
int priv;
printf("priv = %d, pub = %d\n", priv, .omp_data_i->pub);
}
int main(int argc, char *argv[]) {
int priv, pub = 100;
struct .omp_data_s .omp_data_o;
.omp_data_o.pub = pub; // (1)
__builtin_GOMP_parallel_start (main._omp_fn.0, &.omp_data_o, 2);
main._omp_fn.0 (&.omp_data_o);
__builtin_GOMP_parallel_end ();
pub = .omp_data_o.pub; // (2)
return EXIT_SUCCESS;
}
main._omp_fn.0
is the outlined parallel region. struct .omp_data_s
is a structure that holds copies of all primitive (non-array) shared variables referenced in the corresponding parallel region. In this example the only such variable is pub
and therefore struct .omp_data_s
has a single member pub
. The value of each shared variable is copied into this data structure before the parallel region is started (1) and then copied back from the data structure after the parallel region has ended (2).
What happens is that newer versions of GCC do not generate debug information for the struct .omp_data_s
and therefore GDB cannot decode the arguments of the main._omp_fn.0
function. This is not affected by the format of the debug info being generated and I found no option that enables it. I guess it's just GDB not being able to decode the debug info produced by newer GCC's since it works pretty well with Intel's debugger (idb), i.e. it shows both pub
and priv
in info locals
.
When I run your code I get similar results. If you look at the backtrace, it tells you that you are inside an OpenMP environment that is related to how GCC implements OpenMP.
(gdb) backtrace
#0 main._omp_fn.0 () at tmp.c:15
#1 0x000000000040082e in main (argc=1, argv=0x7fffffffe6c8) at tmp.c:7
You can get a value of pub by:
(gdb) up
(gdb) print pub
$1 = 100
but this only gets you the value of pub before the parallel region. You should check the answer by Hristo Iliev for a much more detailed and better description of the situation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With