curl-library
Apparent memory leak deep in cURL library; requesting assistance
Date: Thu, 17 Feb 2011 12:33:23 -0500
I am trying to understand why a 20-byte memory buffer is being leaked every time my code issues an XMLRPC client call. I have ported XMLRPC-C 1.61.31(stable) to Wind River VxWorks 6.4, and am using the client functionality only. The XMLRPC server resides on a remote CPU.
Configuration/setup:
* XMLRPC-C library 1.16.31, downloaded from http://xmlrpc-c.sourceforge.net/ and ported as needed to build & run using Wind River Workbench (GNU C) and VxWorks 6.4. Supporting sub-libraries (util, libutil, curl_transport, expat) are also included in the Workbench project and built.
* cURL library 7.21.3, downloaded from http://curl.haxx.se/ and built with XMLRPC-C into a single downloadable kernel module (library).
* Application-specific functions sitting above XMLRPC-C that make use of the global client and basic client-side APIs (xmlrpc_client_call2, xmlrpc_read_int, etc.).
* All application-level code is written in C and follows the code examples and documented instructions found at http://xmlrpc-c.sourceforge.net/.
I made no functional changes to the cURL library. I simply took the .c and .h files found in the /include/curl and /lib directories of the downloaded source archive and built them into a library using GNU C under Workbench. The only changes I made were to add conditional compile statements to header file include paths, to meet the specific project build needs.
Summary of testing:
* Application code and XMLRPC/cURL library is running on a simulated VxWorks target using Wind River's VxSim capability. Code is debugged and analyzed using the tools supplied with Wind River Workbench, version 2.6. Simulated VxWorks target has networking capability.
* XMLRPC server is a remote Linux host accessed over the internet.
* My application has over 60 API functions, each of which issues one or two XMLRPCs to the remote XMLRPC server. All API functions work correctly. I have successfully retrieved scalar values, strings, structures, and arrays of structures from the remote server and processed them correctly in the application-level code.
* API functions are run in a loop, and each tested API function has been run one time, ten times, and 100 times to assess dynamic memory behavior.
* Wind River's MemScope tool is used to analyze the allocation and freeing of dynamic memory blocks. MemScope logs every single dynamic memory allocation & free, so when a test run is complete it is easy to see any blocks that have not been freed.
Summary of results:
* For every test run, regardless of top-level API function tested and regardless of the number of iterations the API function is run, there is a 20-byte memory leak per RPC. API functions that issue one RPC leak 20 bytes, those that issue two RPCs leak 40 bytes. Perfectly repeatable results, 100% consistent.
* The memory leak occurs deep within the cURL library code (stack trace below), when the function http.c::Curl_http() calls curl_add_buffer() and the CURLM state is CURLM_STATE_DO. This occurs during the xmlrpc_curl_transport.c::performRpc() execution.
MemScope stack trace:
What follows is a text dump of the MemScope output, for a single execution of one API function (that makes a single RPC). This trace shows where the memory leak is observed. The set of four semi-colon-delimited integers after each function name are MemScope data. The only important integer is the last one - it is the current number of bytes allocated & not freed. The last integer of every line should be 0 upon completion of task execution.
This trace was taken after the test had fully completed. I have annotated the lowest five levels of the stack trace to call attention to the source of the 20-byte leak. This repeatable leak is a threat to system stability.
. . issm_running_trial;11;10;1539;20
. . . xmlrpc_client_call;11;10;1539;20
. . . . clientCall_va;11;10;1539;20
. . . . . xmlrpc_client_call2;8;7;1539;20
. . . . . . call;8;7;1539;20
. . . . . . . performRpc;8;7;1539;20
. . . . . . . . performCurlTransaction;8;7;1539;20
. . . . . . . . . finishCurlMulti;8;7;1539;20
. . . . . . . . . . doCurlWork;8;7;1539;20
. . . . . . . . . . . curlMulti_perform;8;7;1539;20
. . . . . . . . . . . . curl_multi_perform;8;7;1539;20
. . . . . . . . . . . . . multi_runsingle;4;3;535;20 <--- curl/multi.c::multi_runsingle()
. . . . . . . . . . . . . . Curl_do;4;3;535;20 <--- curl/url.c::Curl_do()
. . . . . . . . . . . . . . . Curl_http;1;0;20;20 <--- curl/http.c::Curl_http()
. . . . . . . . . . . . . . . . Curl_add_buffer;1;0;20;20 <--- curl/http.c::Curl_add_buffer()
. . . . . . . . . . . . . . . . . malloc;1;0;20;20 <--- VxWorks malloc()
. . . . . . . . . . . . . . . Curl_http;1;1;12;0
. . . . . . . . . . . . . . . . Curl_add_buffer_init;1;1;12;0
. . . . . . . . . . . . . . . . . calloc;1;1;12;0
. . . . . . . . . . . . . . . Curl_http;1;1;488;0
. . . . . . . . . . . . . . . . Curl_add_buffer;1;1;488;0
. . . . . . . . . . . . . . . . . malloc;1;1;488;0
. . . . . . . . . . . . . . . Curl_http;1;1;15;0
. . . . . . . . . . . . . . . . strdup;1;1;15;0
. . . . . . . . . . . . . . . . . malloc;1;1;15;0
. . . . . . . . . . . . . multi_runsingle;2;2;20;0
. . . . . . . . . . . . . multi_runsingle;1;1;964;0
. . . . . . . . . . . . . multi_runsingle;1;1;20;0
. . . . . xmlrpc_client_call2;3;3;80;0
I would appreciate any guidance, suggestions, conclusions (or questions for additional information) regarding this memory leak. Is this an actual leak in the released code that needs to be fixed? Or is there a probable error with the way I've built and use XMLRPC/cURL that is manifesting as this leak?
Thank you for any feedback you are willing to give.
Matt Fisher
matthew.fisher_at_tekelec.com
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2011-02-17