curl-library
About libcurl HTTPS and Multithreading crash
Date: Sun, 4 Mar 2012 14:27:24 +0800
Hi
I asked this issue months back, which is about libcurl crashes when I
request https urls in multithreading manner.
According to your advice, I read through the multithreading and init
global sections in the tutorial, and they seem do not solve my
problem. I have tested the code, attached below, on Centos and Mac
platform, both crashes after I request over few hundreds of urls with
a pool of threads in size of 100 to 200 threads. In contract, if the
code only request Http urls, there is no such problem, it is stable.
I hope you can give me some advice on this, or if this is a know issue
in libcurl. Thank you!
Woods
The dump out information when crashes happen:
----------------------------------------------------------------------------
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1376396384 (LWP 15717)]
0x00649400 in lh_free () from /lib/libcrypto.so.4
(gdb) bt
#0 0x00649400 in lh_free () from /lib/libcrypto.so.4
#1 0x006496ff in lh_insert () from /lib/libcrypto.so.4
#2 0x0064baf5 in ERR_set_implementation () from /lib/libcrypto.so.4
#3 0x0064c434 in ERR_get_state () from /lib/libcrypto.so.4
#4 0x0064c48c in ERR_get_state () from /lib/libcrypto.so.4
#5 0x0064c71d in ERR_peek_error () from /lib/libcrypto.so.4
#6 0x00779a7c in SSL_get_error () from /lib/libssl.so.4
#7 0x08065cdd in ossl_connect_common ()
#8 0x08066ca7 in Curl_ossl_connect ()
#9 0x08053fc4 in Curl_ssl_connect ()
#10 0x08058e21 in Curl_http_connect ()
#11 0x0805f754 in Curl_protocol_connect ()
#12 0x0805ff96 in Curl_setup_conn ()
#13 0x080600a0 in Curl_connect ()
#14 0x0806ca26 in Curl_do_perform ()
#15 0x0804cdaa in ThreadProc () at src/test/testHttp.cpp:49
#16 0x004c65cc in start_thread () from /lib/tls/libpthread.so.0
#17 0x0041e35e in clone () from /lib/tls/libc.so.6
Another crash information is :
------------------------------------------------------------------------------
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1408226400 (LWP 11473)]
0x00649498 in lh_retrieve () from /lib/libcrypto.so.4
(gdb) bt
#0 0x00649498 in lh_retrieve () from /lib/libcrypto.so.4
#1 0x0077d02b in SSL_CTX_flush_sessions () from /lib/libssl.so.4
#2 0x00778fbb in SSL_CTX_free () from /lib/libssl.so.4
#3 0x080637d9 in Curl_ossl_close ()
#4 0x0805d413 in Curl_disconnect ()
#5 0x0806219f in Curl_done ()
#6 0x0806cb21 in Curl_do_perform ()
#7 0x0804cdaa in ThreadProc () at src/test/testHttp.cpp:49
#8 0x004c65cc in start_thread () from /lib/tls/libpthread.so.0
#9 0x0041e35e in clone () from /lib/tls/libc.so.6
My code is :
-------------------------------------------------------------------------------------
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <memory>
#include <pthread.h>
#include <string>
extern "C"
{
#include <curl/curl.h>
}
#include "Semaphore.h"
static Semaphore* pSem = NULL;
using namespace std;
size_t sWriteFunction(void *p_pPtr, size_t p_Size, size_t p_Nmemb,
void *p_pParam)
{
vector<uint8_t> *pHead = reinterpret_cast<vector<uint8_t>*>(p_pParam);
int bytesToRead = p_Size * p_Nmemb;
pHead->insert(pHead->end(), static_cast<uint8_t*>(p_pPtr),
static_cast<uint8_t*>(p_pPtr) + bytesToRead);
return bytesToRead;
}
static void* ThreadProc(void* p_pParam)
{
vector<uint8_t> head;
vector<uint8_t> body;
printf("thread started\n");
string* pUrl = static_cast<string*>(p_pParam);
CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, pUrl->c_str());
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, sWriteFunction);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &head);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, sWriteFunction);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body);
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
CURLcode res = curl_easy_perform(curl);
const char* msg = curl_easy_strerror(res);
printf("result = %s\n", msg);
curl_easy_cleanup(curl);
pSem->Post();
printf("thread exited\n");
return NULL;
}
int main(int argc, char* argv[])
{
if (argc < 3)
{
printf("Usage : %s url.txt poolSize\n", argv[0]);
return 0;
}
printf("Start\n");
// read all urls
FILE* fp = fopen(argv[1], "r");
if (fp == NULL)
{
printf("Invalid file %s\n", argv[1]);
return 0;
}
vector<string> targets;
char line[4096];
while (fgets(line, 4096, fp))
{
string url(line);
if (url.find("https") == 0)
{
targets.push_back(string(line));
}
}
fclose(fp);
int poolSize = atoi(argv[2]);
if (poolSize <= 0)
{
printf("Invalid pool size = %d\n", poolSize);
}
pSem = new Semaphore(poolSize, poolSize);
curl_global_init(CURL_GLOBAL_ALL);
// start to request continuously
while (true)
{
int i = 0;
for (vector<string>::iterator itr = targets.begin(); itr !=
targets.end(); ++itr)
{
pSem->Wait();
pthread_t tid;
pthread_attr_t tattr;
pthread_attr_init(&tattr);
pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
int error = pthread_create(&tid, &tattr, ThreadProc, &(*itr));
if (error != 0)
{
printf("pthread_create error = %d\n", error);
return 0;
}
printf("pthread [%d] created\n", i++);
}
}
delete pSem;
printf("Exit\n");
return 0;
}
-- Woods ------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-library Etiquette: http://curl.haxx.se/mail/etiquette.htmlReceived on 2012-03-04