我有使用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。
我在runnig线程之前运行thread_setup,在加入之后运行thread_cleanup。不幸的是,当我使用很多线程时,我的应用程序仍然随机崩溃。我在调用pthreads_locking_callback之后得到了SIGSEGV,因为我进入了控制台CRYPTO_LOCK_MODE type: 2
。根据backtrace,它在调用OpenSSL_add_all_digests或EVP_DigestUpdate后崩溃。
所以问题是为什么OpenSSL崩溃,因为我正在使用适当的方法来处理多线程程序。我缺少什么?
修改 它不是Tutorial on Using OpenSsl with pthreads的重复,因为正如我所提到的,我已经将这个经典函数用于多线程应用程序。
EDIT2: 有用! 看起来像@Matt Caswell是对的。谢谢你的正确答案。
答案 0 :(得分:3)
所有这些功能:
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<permission
android:name="com.example.permission.MAPS_RECEIVE"
android:protectionLevel="signature"/>
<uses-permission android:name="com.example.permission.MAPS_RECEIVE"/>
库初始化是否正常运行。您应该在调用其他OpenSSL函数之前调用它们一次。这些不是线程安全的。在设置锁定回调之前调用它们。