OpenSSL与OpenMP一起使用,给出了分段错误[重复]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenSSL与OpenMP一起使用,给出了分段错误[重复]相关的知识,希望对你有一定的参考价值。

我在C中使用OpenSSL来搜索双安全素数P.也就是说,我正在寻找素数P使得P = 2p + 1和p = 2p'+ 1,并且p和p'也是素数。这种搜索需要很长时间,因此我使用OpenMP进行多线程处理。这是我的代码:

BIGNUM *p,*p_temp, *P, *P_temp, *temp1,*temp2;

BN_CTX *ctx;

ctx = BN_CTX_new(); 
p = BN_new();
p_temp = BN_new();
P = BN_new();
P_temp = BN_new();
temp1 = BN_new();
temp2 = BN_new();
int doublesafe;
int found;
int ID;
omp_set_num_threads(150);

#pragma omp parallel private(doublesafe,p_temp,P_temp,temp1,temp2,ID) shared(found,P,p,ctx)
{
    ID = omp_get_thread_num();
    printf("
 thread %d", ID);
    found=0;
    while(!found){
       BN_generate_prime_ex(p_temp,1536,1,NULL,NULL,NULL);
       BN_set_word(temp1,2);
       BN_mul(P_temp, temp1, p_temp, ctx);
       BN_add(P_temp, P_temp, BN_value_one());
       doublesafe = BN_is_prime_ex(P_temp,10,ctx, NULL);
       if(doublesafe){
         #pragma omp critical
         {
            if(!found){
            found = 1;
            BN_mul(P, P_temp, BN_value_one(),ctx);
            BN_mul(p, p_temp, BN_value_one(),ctx);
            printf("
 found P! %d", ID);
         }
      }
    }
  }
}
//the parallel block for finding prime p ends here

运行此操作时,我遇到了分段错误:

>Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffb1ae8e700 (LWP 141701)]
0x00007ffff7a9b160 in BN_mod_word () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>(gdb) bt
>#0  0x00007ffff7a9b160 in BN_mod_word () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#1  0x00007ffff7a9d2dd in ?? () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#2  0x00007ffff7a9dd5c in BN_generate_prime_ex () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#3  0x0000000000401e0f in main._omp_fn.0 () at myprogram.c:265
>#4  0x00007ffff77f734a in ?? () from /usr/lib/x86_64-linux-gnu/libgomp.so.1
>#5  0x00007ffff75d9184 in start_thread (arg=0x7ffb1ae8e700) at pthread_create.c:312
>#6  0x00007ffff730603d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

知道原因可能是什么?

我根据祖兰的建议更新了代码。它运行了一次,但是当我再次运行它时会抛出分段错误。更新的代码:

   BIGNUM *p, *P;
   BN_CTX *ctx;
   ctx = BN_CTX_new();
   p = BN_new();
   P = BN_new();
   int found=0;
   omp_set_num_threads(150);
   #pragma omp parallel shared(found,P,p,ctx)
   {
      int ID = omp_get_thread_num();
      printf("
 thread %d", ID);
      int doublesafe=0;
      int local_found=0;
      BIGNUM *P_temp, *p_temp, *temp1;
      p_temp = BN_new();
      P_temp = BN_new();
      temp1 = BN_new();

      while(!local_found){
      BN_generate_prime_ex(p_temp,1536,1,NULL,NULL,NULL);
      BN_set_word(temp1,2);
      BN_mul(P_temp, temp1, p_temp, ctx);
      BN_add(P_temp, P_temp, BN_value_one());
      doublesafe = BN_is_prime_ex(P_temp,10,ctx, NULL);
      if(doublesafe){
      #pragma omp critical
      {
         if(!found){
         found = 1;
         BN_mul(P, P_temp, BN_value_one(),ctx);
         BN_mul(p, p_temp, BN_value_one(),ctx);
         printf("
 found p and P! %d", ID);
      }
      }
      }
    #pragma omp atomic read
    local_found = found;
    }
    }
    //the parallel block for finding safe prime p ends here

我得到以下seg错误:

>Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffb6171b700 (LWP 143091)]
0x00007ffff7a9700c in BN_set_word () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>(gdb) bt
>#0  0x00007ffff7a9700c in BN_set_word () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#1  0x00007ffff7a97c45 in BN_CTX_get () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#2  0x00007ffff7a9d482 in BN_is_prime_fasttest_ex () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
>#3  0x0000000000401c36 in main._omp_fn.0 () at myprogram.c:257
>#4  0x00007ffff77f734a in ?? () from /usr/lib/x86_64-linux-gnu/libgomp.so.1
>#5  0x00007ffff75d9184 in start_thread (arg=0x7ffb6171b700) at pthread_create.c:312
>#6  0x00007ffff730603d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
>(gdb) 

更新:

我注意到调用函数就像

BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb);

BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb);

在并行区域中,大多数时候(并非总是)会引发分段错误。当我评论这些功能时,该程序工作正常。

有谁知道如何处理这个?

我遇到了分段错误,即使我遵循Tutorial on Using OpenSSL with pthreads关于有两个回调函数等的建议。

答案

私有变量未在并行区域内初始化!你必须手动初始化它们 - 更好的是:在并行区域本身声明这些,然后它们是隐式私有的,它更容易被发现。尽可能在本地声明所有变量,并在声明处初始化它们。

同时你的found循环也是错误的。如果found被另一个线程写入,则不得读取use atomics不受保护。即使该写入恰好受到保护。一个解决方案是qazxswpoi,或者你可以使用取消。

以上是关于OpenSSL与OpenMP一起使用,给出了分段错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

将 OpenMP 与 clang 一起使用

无法使 OpenMP 与 CodeBlocks 和 GFortran 一起工作

我可以安全地将 OpenMP 与 C++11 一起使用吗?

循环C ++中的分段错误Openmp

将 OpenMP 与 Fortran 一起使用时出现内存错误,运行 FFTW

C++:使用 OpenMP 插入 std::vector