c - 将 GDB 与 OpenMP 结合使用

标签 c gcc gdb openmp

使用 GDB 我似乎无法在 OpenMP 线程中打印共享变量的值。例如,使用以下程序:

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

在 GDB 中,如果我在第 15 行(第 0 部分的 printf)中断,并尝试打印“pub”的值,我会得到 «No symbol “pub” in current context.»留言:

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.

我正在使用 GCC 进行编译,并尝试了不同的调试标志 (-g3 -ggdb3 -gstabs3 -gstabs+3),但没有成功。我还尝试使用 -O0 禁用所有优化,同样没有成功。但是,我可以使用 -gstabs+ 标志查看私有(private)变量的值。

提前致谢。

最佳答案

GCC 中的 OpenMP 是使用大纲实现的。这意味着每个并行区域的代码都在其自己的函数中提取。例如:

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

转化为:

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 是轮廓平行区域。 struct .omp_data_s 是一种结构,它包含相应并行区域中引用的所有原始(非数组)共享变量的副本。在此示例中,唯一的此类变量是 pub,因此 struct .omp_data_s 具有单个成员 pub。每个共享变量的值在并行区域开始前被复制到这个数据结构中 (1),然后在并行区域结束后从数据结构中复制回来 (2)。

最新版本的 GCC 不会为 struct .omp_data_s 生成调试信息,因此 GDB 无法解码 main._omp_fn.0 函数的参数.这不受正在生成的调试信息格式的影响,而且我没有找到启用它的选项。我想这只是 GDB 无法解码较新的 GCC 产生的调试信息,因为它与 Intel 的调试器 (idb) 配合得很好,即它同时显示 pubprivinfo locals 中。

关于c - 将 GDB 与 OpenMP 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18768674/

相关文章:

c - 将文字地址映射到一个部分

在 C 中从 char 数组创建字符串

objective-c - XCode 构建结果 : why is it so amazingly complex even for a hello world console app?

c++ - Cygwin GDB 在尝试启动程序时出现错误 193

c++ - 一段时间后如何停用输入语句?

c++ - 销毁未初始化的 FFTW 计划是否安全?

c - fatal error : stdio. matrixVector:找不到文件或目录

gcc - 如何在 Mac OS X 主机上为 MIPS 目标构建 GCC 4.8.x

c - gdb "Program exited normally"当它不应该

c - 如何使用gdb在for循环中指定计数器的特定值?