精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
是停止工作崩溃,并不是软件突然没了。界面如下:
点击查看问题详细信息,如下:
问题签名:
问题事件名称: APPCRASH
应用程序名:
应用程序版本: 1.0.0.1
应用程序时间戳: 61cac294
故障模块名称: SSLEAY32.dll
故障模块版本: 1.0.1.7
故障模块时间戳: 5344071d
异常代码:
异常偏移:
OS 版本: 6.1.7601.2.1.0.274.10
区域设置 ID: 2052
其他信息 1: 0a9e
其他信息 2: 0a9e372d3b4ad19135b953a78882e789
其他信息 3: 0a9e
其他信息 4: 0a9e372d3b4ad19135b953a78882e789联机阅读隐私声明:
http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0804如果无法获取联机隐私声明,请脱机阅读我们的隐私声明:
C:\Windows\system32\zh-CN\erofflps.txt
经常细致分析,锐英源软件解决了问题,如果有类似问题,欢迎找锐英源合作解决。
在解决问题过程中,我也找了国外资料,为了加强相关能力,把资料翻译下,让自己提高,也让大家学习,欢迎大家收获本网站。
--------------------------翻译分隔线----------------------------------
我正在尝试在多线程环境中使用 openssl-0.9.7a-23(来自 Fedora 1 的 RPM)。基本上,我有一个大约有 5 个工作线程的服务器和一个连接到服务器的线程数量不等的客户端。在客户端使用大约 20 个线程时,我看不到任何问题。但是当客户端增加到大约 150 个线程时,客户端会出现段错误。服务器从不出现段错误。
gdb 跟踪是:
程序收到信号 SIGSEGV,分段错误。
[切换到线程 -1431196752 (LWP 15771)]
0x00620b84 in _int_malloc () from /lib/tls/libc.so.6
(gdb) where
#0 0x00620b84 in _int_malloc () from /lib/tls/libc.
#1 0x0062170a in _int_realloc () from /lib/tls/libc.so.6
#2 0x0062012f in realloc () from /lib/tls/libc.so.6
#3 0x00b70307 in OpenSSLDie () from /lib/libcrypto.so .4
#4 0x00b70a06 in CRYPTO_realloc () from /lib/libcrypto.so.4
#5 0x00bb84f4 in lh_doall_arg () from /lib/libcrypto.so.4
#6 0x00bb8248 in lh_insert () from /libso.libcrypto.
#7 0x00000001 在 ?? ()
#8 0x00c17210 in CAST_S_table7 () from /lib/libcrypto.so.4
#9 0x000001c4 in ?? ()
(
在 main 中,我调用:
CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
从文档中我不确定的一件事是或不ctx 可以跨多个线程共享。在这一点上,我在任何地方都使用指向相同 ctx 的指针,并在每次连接需要加密时调用 SSL_new 。
关于我需要在哪里解决这个问题的任何想法?
看起来像是某种竞赛条件。
好吧,我建议的第一件事是使用最新的 0.9.7 快照,看看您是否仍然有问题。还要使用调试符号编译 OpenSSL,以便
可以确定崩溃的精确位置(如果仍然发生)。
在多个线程之间使用相同的 SSL_CTX 应该没有问题。但是,如果您的意思是 EVP_CIPHER_CTX,每个线程都应该有自己的,因为状态信息存储在那里。
我很困惑,EVP_CIPHER_CTX 是什么? 我调用 OpenSSL_add_all_algorithms,SSL_load_error_strings,TLSv1_client_method 然后共享SSL_CTX_new调用的返回。 那是 SSL_CTX 还是 EVP_CIPHER_CTX?
如果您共享 SSL_CTX_new 调用的返回,则需要在 libcrypto 中初始化互斥锁,请参阅 CRYPTO_set_locking_callback 。第二种选择是每个线程有一个 SSL_CTX,正如Stephen所提到的。
实际上我已经初始化了锁定回调。让我感到困惑的是 EVP_CIPHER_CTX 的东西,因为我从未见过。
我认为斯蒂芬提到 EVP_CIPHER_CTX 是因为他不确定您在谈论哪个“ctx”。我可以保证共享 SSL_CTX 工作正常,只要互斥锁以正确的方式初始化。
您是否尝试为每个线程使用一个 SSL_CTX 来查看它是否有效?如果此设置有问题,那么它一定来自您的代码,
并且您可能希望在 NG 中发布您的初始化代码。
由于整个系统的复杂性, 将代码更改为每个线程使用一个 SSL_CTX 是一项艰巨的任务。
初始化代码可能更容易看:
我使用:
extern pthread_mutex_t *ggsyscom_ssllock_cs;
extern long *ggsyscom_ssllock_count;
它们在 main.c 文件中定义为全局。
然后,有一个初始化函数,在 main 的开头被调用,它具有(除其他外):
int numlocks = 600;
ggsyscom_ssllock_cs = OPENSSL_malloc(numlocks *
sizeof(pthread_mutex_t));
ggsyscom_ssllock_count = OPENSSL_malloc(numlocks * sizeof(long));
for(i=0; i<numlocks; i++) {
ggsyscom_ssllock_count[i] = 0;
pthread_mutex_init(&(ggsyscom_ssllock_cs[i]),NULL);
}
CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
请注意,我将 numlocks 设置为 600,而不是仅用于测试的定义值。
这里是 pthreads_locking_callback
static void pthreads_locking_callback(int mode, int type, char *file,int
line) {
if (mode & CRYPTO_LOCK)
{
pthread_mutex_lock(&(ggsyscom_ssllock_cs[type]));
ggsyscom_ssllock_count[类型]++;
}
else
{
pthread_mutex_unlock(&(ggsyscom_ssllock_cs[type]));
}
}