OpenSSL与OpenMP一起使用会产生分段错误

时间:2018-01-18 15:48:53

标签: openssl segmentation-fault 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("\n 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("\n 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("\n 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("\n 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关于有两个回调函数等的建议,我也会遇到分段错误。

1 个答案:

答案 0 :(得分:1)

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

同时你的found - 循环也是错误的。如果found被其他线程写入,则不得阅读INFORMATION_SCHEMA.COLUMNS不受保护。即使该写入恰好受到保护。一种解决方案是use atomics,或者您可以使用取消。