我有邏輯簽署其使用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
上得到。根據回溯,它在調用OpenSSL_add_all_digests或EVP_DigestUpdate後崩潰。
所以問題是爲什麼OpenSSL崩潰,因爲我正在使用正確的方法處理多線程程序。我錯過了什麼?
編輯: ,因爲正如我所說,我已經使用這個經典的功能多線程應用程序它是不能重複的Tutorial on Using OpenSsl with pthreads。
編輯2: 它的工作原理! 看起來@Matt Caswell是對的。感謝您的正確答案。
[使用OpenSSL與pthreads的教程]的可能重複(http://stackoverflow.com/questions/3919420/tutorial-on-using-openssl-with-pthreads) –
你怎麼知道這個問題是與OpenSSL和不是用你自己的代碼? –
@AndrewHenle它在一個線程上完美工作,當我使用多線程時崩潰,並且它總是在openssl函數上崩潰。 – user1326505