使用OpenSSL和锁随机崩溃的多线程程序

Multithreaded program using OpenSSL and locks randomly crashes

本文关键字:多线程 程序 崩溃 随机 OpenSSL 使用      更新时间:2023-10-16

我有使用OpenSSL方法签署肥皂文档的逻辑,例如:

OpenSSL_add_all_digests, 
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
OpenSSL_add_all_digests();
EVP_DigestUpdate

等等。当然,用于对文档进行签名的每个逻辑都在不同的线程中运行。

根据有关该主题的许多主题,我创建了用于处理OpenSSL线程的静态类:

unsigned long SomeStaticClass::pthreads_thread_id(){
unsigned long ret;
ret = ( unsigned long )pthread_self();
return ret;
}
void SomeStaticClass::pthreads_locking_callback( int mode, int type, const char* /*file*/, int /*line*/ ){
if( mode & CRYPTO_LOCK ){
printf("CRYPTO_LOCK_MODE type: %dn", type);
pthread_mutex_lock( &( lock_cs[type] ) );
}
else{
printf("UNLOCK type: %dn", type);
pthread_mutex_unlock( &( lock_cs[type] ) );
}
}
void SomeStaticClass::thread_setup(){
printf("THREAD SETUPn");
lock_cs = ( pthread_mutex_t* )OPENSSL_malloc( CRYPTO_num_locks() * sizeof( pthread_mutex_t ) );
for( int i = 0; i < CRYPTO_num_locks(); i++ ){
pthread_mutex_init( &( lock_cs[i] ), NULL );
}
CRYPTO_set_id_callback( SomeStaticClass::pthreads_thread_id );
CRYPTO_set_locking_callback( SomeStaticClass::pthreads_locking_callback );
}
void SomeStaticClass::thread_cleanup(){
printf("THREAD CLEANUPn");
CRYPTO_set_id_callback( NULL );
CRYPTO_set_locking_callback( NULL );
for( int i = 0; i < CRYPTO_num_locks(); i++ ) {
pthread_mutex_destroy( &( lock_cs[i] ) );
}
OPENSSL_free( lock_cs );
}

我离开了printf进行调试。我知道其中一些方法已被弃用,但我只能使用 openssl 0.9.8。

我在运行线程之前运行thread_setup,在加入它们之后运行thread_cleanup。不幸的是,当我使用许多线程时,我的应用程序仍然随机崩溃。我在pthreads_locking_callback打电话后就得到了 SIGSEGV,因为我上了控制台CRYPTO_LOCK_MODE type: 2。根据回溯,它在调用OpenSSL_add_all_digests或EVP_DigestUpdate后崩溃。

所以问题是为什么OpenSSL崩溃,因为我正在使用正确的方法来处理多线程程序。我错过了什么?

编辑:它不是与pthreads一起使用OpenSsl的教程的重复,因为正如我提到的,我已经在多线程应用程序中使用此经典函数。

编辑2:它有效! 看起来@Matt卡斯韦尔是对的。谢谢你的正确答案。

所有这些函数:

SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
OpenSSL_add_all_digests();

是库初始化函数。您应该在调用其他 OpenSSL 函数之前调用它们一次。这些不是线程安全的。在设置锁定回调之前致电他们。