C++ 线程调用中的curl崩溃

C++ 线程调用中的curl崩溃,c++,multithreading,curl,C++,Multithreading,Curl,如果curl是线程安全的,我会阅读SO文章。这段非常简单的代码崩溃了——不总是这样,但当我连续多次调用程序[非并行]时,它会因为分段错误或以下错误而崩溃 到目前为止,我确信我遵守了文档中关于curl和线程的规则 在测试中,我发现它在curl\u easy\u perform()中崩溃 我真的不知道出了什么问题。当我启动程序5次,然后至少有一次它崩溃 我做错了什么?或者根据转储文件,我是否可能正在使用旧的SSL库 要编译的命令行: g++--std=c++11-Wall-Werror-pedant

如果
curl
是线程安全的,我会阅读SO文章。这段非常简单的代码崩溃了——不总是这样,但当我连续多次调用程序[非并行]时,它会因为分段错误或以下错误而崩溃

到目前为止,我确信我遵守了文档中关于
curl
和线程的规则

在测试中,我发现它在
curl\u easy\u perform()
中崩溃

我真的不知道出了什么问题。当我启动程序5次,然后至少有一次它崩溃

我做错了什么?或者根据转储文件,我是否可能正在使用旧的SSL库

要编译的命令行:


g++--std=c++11-Wall-Werror-pedantic-Wextra curl\u crash.cpp-o curl\u crash-lcurl-rdynamic&./curl\u crash

我过早停止阅读SSL库文档。多亏了
Petesh
,他在访问
openssl
时指出了这个问题,我才能够快速解决这个问题

正如
curl
文档-->
TLS
-->
OpenSSL
中所述,我必须使用这些函数。我将其改编为C++11标准:

#include <mutex>
#include <openssl/err.h>
#include <vector>

class SslCurlWrapper
{
private:
    static std::vector<std::mutex> vectorOfSslMutex;
    static auto id_function() -> unsigned long { return ( pthread_self() ); }
    static auto locking_function(int, int, const char *, int) -> void;

public:
    SslCurlWrapper();
    ~SslCurlWrapper();
};

std::vector<std::mutex> SslCurlWrapper::vectorOfSslMutex( CRYPTO_num_locks() );

//----------------------------------------
auto SslCurlWrapper::locking_function( int mode,
                                       int n,
                                       __attribute__ ((unused)) const char * file,
                                       __attribute__ ((unused)) int line
                                     ) -> void
//----------------------------------------
{
    if ( mode & CRYPTO_LOCK )   vectorOfSslMutex [n].lock();
    else                        vectorOfSslMutex [n].unlock();
}

//------------------------------
SslCurlWrapper::SslCurlWrapper()
//------------------------------
{
    CRYPTO_set_id_callback( id_function );
    CRYPTO_set_locking_callback( locking_function );
}

//-------------------------------
SslCurlWrapper::~SslCurlWrapper()
//-------------------------------
{
    CRYPTO_set_id_callback( nullptr );
    CRYPTO_set_locking_callback( nullptr );
}
编译命令:

g++ -std=c++11 -Wall -Werror -Wextra -pedantic -c SslCurlWrapper.cpp
必须将
-lcrypto
库添加到编译器命令行,以便链接器不会抱怨

我个人的意见是,我有点惊讶于
openssl
库中的默认模式没有实现上述两个函数,从而避免每个程序员必须从头开始。这可能是最低限度的实施

测试shell脚本调用程序200次,没有任何崩溃。在它立即坠毁之前。对我来说,它是固定的


我不理解SergeyA的无用评论。

您的代码几乎违反了内存管理的所有可能规则。预计它会坠毁。@SergeyA很高兴知道是哪个。非常感谢。有趣的是根本没有任何内存管理。。。这是一个非常简单的测试用例。@AlBundy请参阅。这似乎表明您缺少openssl的一些锁定;这是让curl以多线程方式正常工作所必需的。哇!谢谢你的这篇文章。我还是不敢相信。我一整天都在试图找到一个bug,我意识到我有openssl 1.0.2,我遇到了这个问题。再补充一点信息:我目前正在努力解决这个问题。尝试了curl站点中建议的代码(使用pthreads库)但没有成功,然后汇总了一段与您的代码非常相似的代码。似乎更具弹性,但最终在压力测试中以相同的堆栈跟踪失败。这是一个很难解决的问题,因为您不可能在运行时捕获它并恢复操作。。。在openSSL中,当同时发生多个同步握手时,这似乎是一个错误。希望它对你有用:)@Thermalboroman我很抱歉读到这个。我在我的项目中使用这个解决方案,最多可以同时有100个线程。它就像一个符咒。您正在使用哪个CURL库?你收到分割错误吗?事实上,就在几分钟前,我让它工作了。上午的大部分时间我都在摸索这个问题,将问题追溯到openssl库并阅读相关文献。尝试使用1.0.1f似乎可以解决问题,因为我们已经处理了大约30000个请求,这些请求分布在40多个线程上,一台机器上没有问题,而另一台机器则随机崩溃并丢失数据。。。我的显影机肯定有些可疑:)。没有故障,只是内存损坏。libcurl/7.35.0。谢谢分享@马尔博罗曼:-)
#include <mutex>
#include <openssl/err.h>
#include <vector>

class SslCurlWrapper
{
private:
    static std::vector<std::mutex> vectorOfSslMutex;
    static auto id_function() -> unsigned long { return ( pthread_self() ); }
    static auto locking_function(int, int, const char *, int) -> void;

public:
    SslCurlWrapper();
    ~SslCurlWrapper();
};

std::vector<std::mutex> SslCurlWrapper::vectorOfSslMutex( CRYPTO_num_locks() );

//----------------------------------------
auto SslCurlWrapper::locking_function( int mode,
                                       int n,
                                       __attribute__ ((unused)) const char * file,
                                       __attribute__ ((unused)) int line
                                     ) -> void
//----------------------------------------
{
    if ( mode & CRYPTO_LOCK )   vectorOfSslMutex [n].lock();
    else                        vectorOfSslMutex [n].unlock();
}

//------------------------------
SslCurlWrapper::SslCurlWrapper()
//------------------------------
{
    CRYPTO_set_id_callback( id_function );
    CRYPTO_set_locking_callback( locking_function );
}

//-------------------------------
SslCurlWrapper::~SslCurlWrapper()
//-------------------------------
{
    CRYPTO_set_id_callback( nullptr );
    CRYPTO_set_locking_callback( nullptr );
}
int main(void)
{
        SslCurlWrapper sslObject;    // hook is set up
        // here it is safe to use the curl library in a multi-thread-environment
}       // hook is released/uninstalled
g++ -std=c++11 -Wall -Werror -Wextra -pedantic -c SslCurlWrapper.cpp