curl-library
crash using libcurl 7.19 multi interface
Date: Thu, 12 Mar 2009 16:53:29 +0100
Hi,
for days I've been trying to figure out a crash appearing in one of
our unit tests that uses libcurl's multi interface. The app sometimes
crashes in 'Curl_llist_insert_next()' ("llist.c"). This is on Win32
where I had it crashing in ~50% of all runs. (The program did crash
on Linux and OSX, too, but only very rarely and nobody investigated
whether it's even the same issue.)
I have boiled the problem down to the attached program. I would very
much appreciate it if someone could have a look at it and tell me
whether there's something stupid in there that causes the problem.
To me thsi very much looks like this must be a bug in libcurl, but
since I hadn't used libcurl before I was assigned the task to find
out about this, I might overlook something very stupid. If so, then
this might be the/an issue in the original code or I might have
introduced it when I tried to isolate the problem.
Thanks in advance!
Schobi
#include <iostream>
#include <string>
#include <sstream>
#include <curl/curl.h>
template< typename T >
std::string as_string(const T& obj)
{
std::ostringstream oss;
oss << obj;
if( !oss ) {
std::cerr << "Dang!\n";
std::exit(42);
}
return oss.str();
}
void checkCurlStatus(CURLcode theStatusCode) {
if (theStatusCode != CURLE_OK) {
std::cerr << "Dang!\n";
std::exit(1);
}
}
void checkCurlStatus(CURLMcode theStatusCode) {
if (theStatusCode != CURLM_OK && theStatusCode != CURLM_CALL_MULTI_PERFORM) {
std::cerr << "Dang!\n";
std::exit(2);
}
}
int main(int /*argc*/, char** /*argv*/)
{
const int runningCount = 1000;
std::cout << curl_version();
curl_global_init(CURL_GLOBAL_ALL);
CURLM * myCurlMultiHandle = curl_multi_init();
for( unsigned int u = 0; u< runningCount; ++u ) {
const std::string myURL = "http://go.microsoft.com/fwlink/?LinkId="+as_string(10000+u);
CURL * myCurlHandle = curl_easy_init();
CURLcode myStatus = curl_easy_setopt(myCurlHandle, CURLOPT_URL, myURL.c_str());
checkCurlStatus(myStatus);
CURLMcode myMStatus = curl_multi_add_handle(myCurlMultiHandle, myCurlHandle);
checkCurlStatus(myMStatus);
}
int myRunningCount = runningCount;
std::cerr << "Handling " << myRunningCount << " requests...\n";
while (myRunningCount) {
CURLMcode myStatus;
int myNewRunningCount;
do {
myStatus = curl_multi_perform(myCurlMultiHandle, &myNewRunningCount);
checkCurlStatus(myStatus);
CURLMsg * myMessage = 0;
do {
int myMessageCount = 0;
myMessage = curl_multi_info_read(myCurlMultiHandle, &myMessageCount);
if (myMessage) {
if (myMessage->msg == CURLMSG_DONE) {
std::cerr << "Dang!\n";
std::exit(3);
}
checkCurlStatus(myMessage->data.result);
}
} while (myMessage);
} while (myStatus == CURLM_CALL_MULTI_PERFORM);
if( myRunningCount != myNewRunningCount ) {
std::cerr << "Request handled, " << myNewRunningCount << " requests left to handle.\n";
}
myRunningCount = myNewRunningCount;
}
std::cerr << "...curl finished handling requests.\n";
return 0;
}
Received on 2009-03-12