Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
870 views
in Technique[技术] by (71.8m points)

c - Using GDB with OpenMP

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
", tid, priv, pub);
      }
      #pragma omp section
      {
        printf("SECTION 1: tid=%d, priv=%d, pub=%d
", 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
", 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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
", 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
", 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...