curl-library
known memory leak in simple easy calls in version 17?
Date: Wed, 20 Aug 2008 22:03:43 -0600
I have a definite memory leak happening with a simple test (source below). I question whether this is a curl issue or not as I was
confident up until now that the version 17 code for these simple easy calls is stable. This is too simple a problem to exist in
that mature code base (I think).
Please take a quick look at the test win32 proc to see if there is anything obvious. If I comment out the call to easy perform
there is no memory increase in the test process. If the call to easy perform is there is seems to burn through about 512-1024 bytes
per call.
If I remove the write buffering, there is no change.
If I comment out the call to easy perform there is not memory gain by the test process.
Are there any known memory leak issues like this in the version 17 code?
This test is performing a complete global init and cleanup every loop, so perhaps that is the problem, although this test was
supposed to prove that our memory leak in this test app was not in the curl code.
Thanks,
Max
----- snip
// =====================================================================
// RPCURLTst17a proc
//
// this proc is for testing curl easy code 7.17.1 to identify a suspect
// memory leak during perform curl call ...
//
// =====================================================================
ULONG RPCURLTst17a ( UCHAR *szURL ) // ping URL, return codes tbd
{
CURL *curlhPing ; // libcurl ping easy handle
CURLcode res ; // result code from libcurl
// setup memory structures for memory
struct MemoryStruct writeBuffer = { '\0', 0, 0 } ;
BOOL bCurlGlobalInitDone = FALSE ; // set when global init done
if ( !bCurlGlobalInitDone )
{
// -------------------------------------------------------------
// setup libcurl global info for win32, global cleanup on exit
// -------------------------------------------------------------
if ( curl_global_init ( CURL_GLOBAL_ALL | CURL_GLOBAL_WIN32 ) )
{
strcpy ( ucCURLErrorBuffer, // defined globally in rpv7.h
"libcurl global init error in RPCommsPing" ) ;
return ( CURLGLOBALINITFAIL ) ; // ^^^^^^^^^^^^^^^^^^^^^^^^^
} // end of call to curl global init failed
// -------------------------------------------------------------
// CURL global initialization is now done or we exited with a
// failure code
// -------------------------------------------------------------
} // end of if global init not done
// -----------------------------------------------------------------
// ok, curl global init was successful, so set flag to curl global
// cleanup on exit
// -----------------------------------------------------------------
bCurlGlobalInitDone = TRUE ; // make sure ut global cleanup on exit
// -----------------------------------------------------------------
// now, setup the test operation
// -----------------------------------------------------------------
curlhPing = curl_easy_init ( ) ; // get curl handle
if ( !curlhPing ) // zero means no handle, failed
{
// failed to get easy handle, so global cleanup and ABEND
if ( bCurlGlobalInitDone)
{
curl_global_cleanup ( ) ; // clean up environment
bCurlGlobalInitDone = FALSE ;
}
strcpy ( ucCURLErrorBuffer, "libcurl easy init error" ) ;
return ( CURLEASYINITFAIL ) ; // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
} // end of if !curl call to curl init failed
// -----------------------------------------------------------------
// set up a call back to process the website returned data in
// bytes terminated by a null and storage for the write function
// -----------------------------------------------------------------
curl_easy_setopt (
curlhPing, // ping curl handle
CURLOPT_WRITEFUNCTION, // setup write callback
RPCommsCurlWriteDataToMemory // our write callback
) ;
// -----------------------------------------------------------------
// as the write function picks up bytes have it copied to our
// write buffer with a null termination byte (see
// WriteDataToMemory proc for details)
// -----------------------------------------------------------------
curl_easy_setopt (
curlhPing,
CURLOPT_WRITEDATA,
&writeBuffer
) ;
// -----------------------------------------------------------------
// if there are any errors, make sure we know what libcurl says
// is going on in a global buffer
// -----------------------------------------------------------------
curl_easy_setopt (
curlhPing,
CURLOPT_ERRORBUFFER,
ucCURLErrorBuffer
) ;
// -----------------------------------------------------------------
// curl fails on 400+ error codes from the server - it's unclear
// if this does anything useful for our ping example, but it is
// in the planned production design, so it is here too ...
// -----------------------------------------------------------------
curl_easy_setopt ( curlhPing, CURLOPT_FAILONERROR, TRUE ) ;
// -----------------------------------------------------------------
// setup our test URL every time for this test
// -----------------------------------------------------------------
curl_easy_setopt ( // setup URL to touch
curlhPing,
CURLOPT_URL,
szURL // URL passed in RPCommsPing proc
) ;
// -----------------------------------------------------------------
// check the msecs before and after the call to easy perform in
// global ulPingPerformMSecs
// -----------------------------------------------------------------
res = curl_easy_perform ( curlhPing ) ; // <<<<< ----- PING !
// -----------------------------------------------------------------
// cleanup memory allocation by write callback
if ( writeBuffer.memory )
free ( writeBuffer.memory ) ;
writeBuffer.lastSize = 0 ;
writeBuffer.memory = 0 ;
writeBuffer.size = 0 ;
// -----------------------------------------------------------------
// cleanup after libcurl
// -----------------------------------------------------------------
curl_easy_cleanup ( curlhPing ) ; // end of easy session
// -------------------------------------------------------------
// free up global resources -
// -------------------------------------------------------------
if ( bCurlGlobalInitDone ) // do global cleanup before exiting
{
curl_global_cleanup ( ) ; // clean up environment
bCurlGlobalInitDone = FALSE ; // show we are no longer init'd
}
return ( res ) ; //
} // end of RPCommsPing proc
// =====================================================================
Received on 2008-08-21