繁体   English   中英

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

[英]Multithreaded program using OpenSSL and locks randomly crashes

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

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: %d\n", type);
                pthread_mutex_lock( &( lock_cs[type] ) );
        }
        else{
                printf("UNLOCK type: %d\n", type);
                pthread_mutex_unlock( &( lock_cs[type] ) );
        }
}

void SomeStaticClass::thread_setup(){

        printf("THREAD SETUP\n");
        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 CLEANUP\n");
        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 会崩溃,因为我使用了正确的方法来处理多线程程序。 我缺少什么?

编辑:它不是将 OpenSsl 与 pthreads 一起使用教程的副本,因为正如我所提到的,我已经将这个经典函数用于多线程应用程序。

EDIT2:它有效! 看起来@Matt Caswell 是对的。 谢谢你的正确答案。

所有这些功能:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM