Спасибо Jww, пожалуйста, смотрите обновление на вопрос.

ользую OpenSSL в многопоточной программе на C и возникают проблемы. Поэтому я написал небольшую программу, чтобы попытаться сузить суть проблемы. Функции помимо основной функции были скопированы изhttps://github.com/plenluno/openssl/blob/master/openssl/crypto/threads/mttest.c

Моя программа выглядит следующим образом.

   #include<stdio.h>  
   #include<stdlib.h>
   #include<stdarg.h>
   #include <strings.h>
   #include <string.h>
   #include <math.h>
   #include <sys/stat.h>
   #include <fcntl.h>
   #include <unistd.h>
   #include<omp.h>
   #include <openssl/bn.h>
   #include <openssl/dh.h>
   #include <openssl/crypto.h>
   #include <pthread.h>
   #include <openssl/lhash.h>
   #include <openssl/buffer.h> 
   #include <openssl/x509.h>
   #include <openssl/ssl.h>
   #include <openssl/err.h>

   static pthread_mutex_t *lock_cs;
   static long *lock_count;

   void pthreads_locking_callback(int mode, int type, char *file,
     int line)
  {
   #if 0
      fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
      CRYPTO_thread_id(),
      (mode&CRYPTO_LOCK)?"l":"u",
      (type&CRYPTO_READ)?"r":"w",file,line);
   #endif
   #if 0
     if (CRYPTO_LOCK_SSL_CERT == type)
     fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
     CRYPTO_thread_id(),
     mode,file,line);
   #endif
   if (mode & CRYPTO_LOCK)
    {
    pthread_mutex_lock(&(lock_cs[type]));
    lock_count[type]++;
    }
    else
    {
    pthread_mutex_unlock(&(lock_cs[type]));
    }
   }

 unsigned long pthreads_thread_id(void)
 {
 unsigned long ret;

 ret=(unsigned long)pthread_self();
return(ret);
 }

void CRYPTO_thread_setup(void)
{
 int i;

 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * 
  sizeof(pthread_mutex_t));
lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
for (i=0; i<CRYPTO_num_locks(); i++)
    {
    lock_count[i]=0;
    pthread_mutex_init(&(lock_cs[i]),NULL);
    }

CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
}

 void thread_cleanup(void)
 {
       int i;
       CRYPTO_set_locking_callback(NULL);
       for (i=0; i<CRYPTO_num_locks(); i++)
       {
           pthread_mutex_destroy(&(lock_cs[i]));
       }
  OPENSSL_free(lock_cs);
  OPENSSL_free(lock_count);
  }

  int main(){

   BN_CTX *ctx;
   ctx = BN_CTX_new();

   omp_set_num_threads(158);
   #pragma omp parallel
   {

          int ID = omp_get_thread_num();
          BIGNUM *b,*e,*r,*m;
          b = BN_new();
          e = BN_new();
          r = BN_new();
          m = BN_new();
          BN_set_word(b, 9);
          BN_set_word(e, 3);
          BN_set_word(m, 5);
          BN_mod_exp(r,b,e,m,ctx);
          char* result = BN_bn2dec(r);
          printf("\n thread = %d result = %s", ID, result); fflush(stdout);
          }

          thread_cleanup();

        }

Я получаю следующую ошибку и обратную трассировку, которая говорит мне, что проблема в BN_mod_exp (r, b, e, m, ctx).

  Program received signal SIGSEGV, Segmentation fault.
  [Switching to Thread 0x7fffa9f69700 (LWP 151994)]
  0x00007ffff7a97bb6 in BN_CTX_end () from /lib/x86_64-linux-
  gnu/libcrypto.so.1.0.0
  (gdb) bt
  #0  0x00007ffff7a97bb6 in BN_CTX_end () from /lib/x86_64-linux-
  gnu/libcrypto.so.1.0.0
  #1  0x00007ffff7a940cd in BN_div () from /lib/x86_64-linux-
  gnu/libcrypto.so.1.0.0
  #2  0x00007ffff7aa3dff in BN_MONT_CTX_set () from /lib/x86_64-
  linux-gnu/libcrypto.so.1.0.0
  #3  0x00007ffff7a963e5 in BN_mod_exp_mont_word () from /lib/x86_64-
  linux-gnu/libcrypto.so.1.0.0
  #4  0x0000000000400fef in main._omp_fn.0 () at 
  debuggingsession.c:106
  #5  0x00007ffff77f734a in ?? () from /usr/lib/x86_64-linux-
  gnu/libgomp.so.1
  #6  0x00007ffff75d9184 in start_thread (arg=0x7fffa9f69700) at 
  pthread_create.c:312
  #7  0x00007ffff730603d in clone () at 
  ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
  (gdb) frame 4
   #4  0x0000000000400fef in main._omp_fn.0 () at 
   debuggingsession.c:106
  106       BN_mod_exp(r,b,e,m,ctx);
  (gdb) print r
  $1 = (BIGNUM *) 0x7fff8c000900
  (gdb) x 0x7fff8c000900
  0x7fff8c000900:   0x00000000
  (gdb) print b
   $2 = (BIGNUM *) 0x7fff8c0008c0
   (gdb) x 0x7fff8c0008c0
   0x7fff8c0008c0:  0x8c000940
   (gdb) x 0x8c000940
   0x8c000940:  Cannot access memory at address 0x8c000940
   (gdb) print b
   $3 = (BIGNUM *) 0x7fff8c0008c0
   (gdb) print e
   $4 = (BIGNUM *) 0x7fff8c0008e0
   (gdb) print m
   $5 = (BIGNUM *) 0x7fff8c000920
   (gdb) x

Обновление: я использую OpenSSL и OpenMP в более крупной программе, выше только для отладки. В более крупной программе я настроил несколько потоков, и каждый из них должен писать в свой собственный файл (а не в один и тот же файл). Отсюда:https://en.wikibooks.org/wiki/OpenSSL/Initialization они говорят, что обратные вызовы потока должны быть установлены перед функциями инициализации. Я предполагаю, что это означает, что сначала мы вызываем CRYPTO_thread_setup (), а затем функции инициализации библиотеки OpenSSL. Откуда нужно вызывать CRYPTO_thread_setup (), это сразу после первой параллели #pragma omp и перед открывающей скобкой? Когда я помещаю его туда вместе с функциями инициализации библиотеки, я все еще получаю ошибки сегментации, на этот раз связанные с использованием fclose () внутри потоков. Любые идеи о том, почему это может происходить?

Ответы на вопрос(0)

Ваш ответ на вопрос