Using GDB with OpenMP

Using GDB I cannot print the value of shared variables in OpenMP streams. 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 line 15 (printf of section 0) and I try to print the value "pub", I get the pub "No symbol" in the 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 compile with GCC and unsuccessfully try various debug flags (-g3 -ggdb3 -gstabs3 -gstabs + 3). I also tried disabling all optimizations with -O0, again without success. However, I see the value of private variables using the -gstabs + flag.

Thanks in advance.

+4
source share
2 answers

When I run my code, I get similar results. If you look at the backtracking, it will tell you that you are in an OpenMP environment 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 the pub value:

 (gdb) up (gdb) print pub $1 = 100 

but it only gives you the pub value in front of the parallel region. You should check Khrili Iliev’s answer for a more detailed and better description of the situation.

+2
source

OpenMP in GCC is implemented using allocation. This means that the code for each parallel area is extracted in its own function. For instance:

 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; } 

converted to:

 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 designated parallel area. struct .omp_data_s is a structure that contains copies of all the primitive (not array) common variables mentioned in the corresponding parallel area. In this example, the only such variable is pub , and therefore struct .omp_data_s has a single pub member. The value of each shared variable is copied to this data structure before the start of the parallel region (1), and then is copied back from the data structure after the end of the parallel region (2).

What happens is that newer versions of GCC do not generate debugging information for struct .omp_data_s , and therefore GDB cannot decode the arguments to main._omp_fn.0 . This is not affected by the format of the generated debugging information, and I have not found an option that allows this. I assume that simply GDB will not be able to decode the debugging information generated by the newer GCC, since it works very well with the Intel debugger (idb), i.e. shows both pub and priv in info locals .

+10
source

Source: https://habr.com/ru/post/1501888/


All Articles