多线程程序在 HTTPS 请求上崩溃

Posted

技术标签:

【中文标题】多线程程序在 HTTPS 请求上崩溃【英文标题】:Multithreaded program crashes on HTTPS requests 【发布时间】:2014-05-06 06:11:34 【问题描述】:

在我的多线程应用程序中,我尝试使用 curl(带有 openssl)来执行 HTTPS 请求。

我已根据此信息阅读并制作了所有内容:

libcurl programming tutorial http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION Network Security with OpenSSL: Cryptography for Secure Communications

应用程序因 SEGFAULT 11 和下一个调用堆栈而崩溃:

#0 0x00007f62446014d0 in X509_STORE_add_lookup () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 #1 0x00007f62445fa49f 在 X509_STORE_load_locations () 来自 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 #2 0x00007f6246a268c5 在?? () 来自 /usr/lib/x86_64-linux-gnu/libcurl.so.4 #3 0x00007f6246a27b15 in Curl_ossl_connect () from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #4 0x00007f6246a3b0b9 in Curl_ssl_connect () from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #5 0x00007f6246a11f80 in Curl_http_connect () from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #6 0x00007f6246a22bea in Curl_protocol_connect () from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #7 0x00007f6246a22e9a in Curl_setup_conn () from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #8 0x00007f6246a22f44 in Curl_connect() from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #9 0x00007f6246a2e2a1 在?? () 来自 /usr/lib/x86_64-linux-gnu/libcurl.so.4 #10 — 这是我的 curl_easy_perform(curl) 代码;

此外,我发现 curl multithread example 也崩溃了,使用 SEGFAULT 和相同的调用堆栈:

#0 0x00007fe954d454d0 in X509_STORE_add_lookup () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 #1 0x00007fe954d3e49f 在 X509_STORE_load_locations () 来自 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 #2 0x00007fe955d1f8c5 在?? () 来自 /usr/lib/x86_64-linux-gnu/libcurl.so.4 #3 0x00007fe955d20b15 in Curl_ossl_connect () from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #4 0x00007fe955d340b9 in Curl_ssl_connect () from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #5 0x00007fe955d0af80 in Curl_http_connect() from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #6 0x00007fe955d1bbea in Curl_protocol_connect () from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #7 0x00007fe955d1be9a in Curl_setup_conn () from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #8 0x00007fe955d1bf44 in Curl_connect () from /usr/lib/x86_64-linux-gnu/libcurl.so.4 #9 0x00007fe955d272a1 在?? () 来自 /usr/lib/x86_64-linux-gnu/libcurl.so.4 #10 0x000000000044251d in pull_one_url (url=0x44cac4) at ../src/Main.cpp:124 #11 0x00007fe955001e9a in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0 #12 0x00007fe95530b3fd in clone () from /lib/x86_64-linux-gnu/libc.so.6 #13 0x0000000000000000 在 ?? ()

我的系统: Ubuntu 12.04 x64,OpenSSL 1.0.1 GCC 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

UPD1: 在逐行删除所有代码后,我发现我的应用程序(以及 CURL 示例,我在 main func 之前添加了该代码)在下一个代码存在时崩溃(即使它没有从任何地方调用!!!):

#include "openssl/md5.h"
char* MD5_dcsadcsa(char* dest, const char* src, size_t length)

    unsigned char result[MD5_DIGEST_LENGTH];
    ::MD5((unsigned char*) src, length, result);
    for(int i = 0; i < MD5_DIGEST_LENGTH; ++i)
        sprintf(&dest[2 * i], "%02x", result[i]);
    return dest;

g++ -D_DEBUG -I/usr/include/boost -I/usr/include/mysql -O2 -ggdb -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT" main.d" -o "main.o" "main.cpp" g++ -o "app_backend" main.o -lmysqlclient_r -lcurl -lgnutls-openssl ./app_backend

线程 0,获取 https://www.example.com/ 线程 1,获取 https://www2.example.com/ 线程 2,获取 https://www3.example.com/ 线程 3,获取 https://www4.example.com/ 分段错误(核心转储)

UPD2: 使用 MD5 调用注释的应用不会粉碎

//::MD5((unsigned char*) src, length, result);

【问题讨论】:

显示 main.cpp 文件的相关部分。 您是否安装了 OpenSSL 所需的静态锁?请参阅 OpenSSL 文档中的 threads(3)。 你是如何编译你的程序和 curl 例子的? 【参考方案1】:

我刚刚删除了 -lgnutls-openssl 并且它有效。 我在以前版本的应用程序中使用它仅用于计算 md5 校验和。

【讨论】:

以上是关于多线程程序在 HTTPS 请求上崩溃的主要内容,如果未能解决你的问题,请参考以下文章

多线程,如果线程崩溃,应用程序会发生啥

多线程 Win32 C++ 程序在多个线程中使用 try/catch 崩溃

多线程并发会造成程序周期性崩溃吗?

多线程渲染仅在 iOS 13 上崩溃

在多线程环境中访问数组会导致应用程序崩溃

核心数据和多线程在保存时崩溃