Programa multiproceso segfaults con OpenSSL y OpenMP

Estoy usando OpenSSL en un programa multiproceso en C y tengo problemas. Entonces escribí un pequeño programa para tratar de reducir cuál es el problema. Las funciones además de la función principal se copiaron dehttps://github.com/plenluno/openssl/blob/master/openssl/crypto/threads/mttest.c

Mi programa es el siguiente.

   #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();

        }

Recibo el siguiente error y retroceso, que me dice que BN_mod_exp (r, b, e, m, ctx) es el problema.

  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

Actualización: estoy usando OpenSSL y OpenMP en un programa más grande, lo anterior fue solo para la depuración. En el programa más grande, configuro varios hilos y se supone que cada uno debe escribir en su propio archivo (no en el mismo archivo). De aquí:https://en.wikibooks.org/wiki/OpenSSL/Initialization dicen que las devoluciones de llamada de subprocesos deben configurarse antes de las funciones de inicialización. Supongo que lo que esto significa es que primero llamamos CRYPTO_thread_setup (), y luego las funciones de inicialización de la biblioteca OpenSSL. ¿Desde dónde debe llamarse CRYPTO_thread_setup (), es inmediatamente después del primer paralelo de #pragma omp y antes de la llave de apertura? Cuando lo puse allí, junto con las funciones de inicialización de la biblioteca, todavía recibo fallas de segmentación, esta vez relacionadas con el uso de fclose () dentro de los hilos. ¿Alguna idea de por qué esto podría estar sucediendo?

Respuestas a la pregunta(0)

Su respuesta a la pregunta