【问题标题】:Segmentation fault in snprintf when using OpenMP使用 OpenMP 时 snprintf 中的分段错误
【发布时间】:2014-09-09 15:10:40
【问题描述】:

我在某处读到 snprintf 是线程安全的;但是,当我运行我的代码时,它会产生分段错误。

主要功能:

#pragma omp parallel 
{
    #pragma omp for private(j)
    for (i = 0; i < 8; i++) {
        for (j = 0; j < 1; j++) {
            foo(gene_seq); //gene_seq is a large char array
        }
    }
}

以及出错的代码行:

double foo(char *gene_seq){
    char *seq;

    /* some stuff above */
    region_length = end_pos-init_pos+1; // include \0 terminator
    seq = (char *)safe_malloc(sizeof(char) * region_length);
    snprintf(seq, region_length, "%s", gene_seq + init_pos); //SIGSEGV!!!
    /*more stuff*/
}

编辑将 snprintf 行周围的程序更新为:

#pragma omp critical
{
    snprintf(seq, region_length, "%s", gene_seq + init_pos);
}

它仍然无法执行。 gdb 为我提供了以下变量值:

(gdb) p strlen(gene_seq)
$1 = 1405
(gdb) p init_pos
$2 = 683
(gdb) p region_length
$4 = 221   

当我执行单线程程序时,它运行良好,而 gdb 不是很有帮助。我的 glibc 版本是 2.15。如果需要,将提供更多信息。

【问题讨论】:

  • 你读到了gene_seq的结尾吗?
  • 我不认为snprintf 通常是线程安全的。也许您读过一个特定的实现是?当然,如果您记得在哪里看到的,那会有所帮助。
  • @PascalCuoq 这里的第一个答案:stackoverflow.com/questions/13386352/is-sprintf-thread-safe
  • 也许您阅读gene_seq 来计算这些变量并出于其他原因写入它,使这些变量具有奇怪 值。
  • @alk 这个评论好像是一个答案

标签: c multithreading openmp


【解决方案1】:

你可能错过了safe_malloc() 的原型并且是 64 位的吗?

如果“是”,编译器假定 safe_alloc() 返回 32 位,因此如果指针的值大于 2^32,则返回无效指针。

打开所有警告 -Wall -Wextra -pedantic 并聆听编译器告诉你的内容。

【讨论】:

  • 问题确实是缺少原型,导致safe_malloc 调用出现一些奇怪的行为。打开警告帮助我找到了问题!
  • 我还花时间说 snprintf 在所提出问题的范围内似乎是线程安全的。
  • man 7 pthreads (man7.org/linux/man-pages/man7/pthreads.7.html) 指的是哪些函数应该是线程安全的,哪些不是在哪些假设下。 @ManuelReis
猜你喜欢
  • 1970-01-01
  • 2015-10-14
  • 1970-01-01
  • 1970-01-01
  • 2020-06-13
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
相关资源
最近更新 更多