Solaris Sustaining Engineer
Sriram Popuri's Weblog
Archives
« November 2009
SunMonTueWedThuFriSat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
     
       
Today
XML
Search

Links
OpenSolaris User Group OpenSolaris: Love at First Boot
Referrers

Today's Page Hits: 45

« Want to know Solaris... | Main | Our first Bangalore... »
20050616 Thursday June 16, 2005
Wrapper library to track memory leaks
Recently with the help of Moinak and Kishore I wrote a wrapper library which dumps memory leaks. Thought of talking about it here. You can use libumem to identify memory leaks. I feel libumem is a powerful tool to identify memory leaks. The tool we developed is a simple one and just only done for learning stuff. Idea was to write a wrapper library which we can just preload it to the app. What the idea was to track all memory allocations which are not freed. atexit, registered reportalloc (function which reports allocation), so on program termination we get the dump of all memory allocations which are not freed. Not only I report at the exit, we can also get a dump of all allocations when a particular signal is sent to the program. You can set an environment variable SIGNAL_USED to a signal which is unused in the program (How do you find which signals don't have handlers...use psig on the process). wrapper library will handle that signal, so when ever you send a signal $SIGNAL_USED to the process it dumps all allocations at that instance. We wrote wrappers for malloc, calloc, realloc, valloc and free.

How we got stack trace? We got the stack frames and extracted return addresses and using dladdr to find symbolic information.

Some codesnips of the library is below. Only writng malloc here as other are almost similar except calloc which has an extra argument. void *malloc(size_t size) { void *buf; /* dlinit will initialize global function pointers which will * point to the original libc functions. */ dlinit(); /* mptr is a function pointer to libc malloc */ buf = (*mptr)(size); /* We add the data to a hashed list * what each node in the hashed chain contains * is the address returned, stack trace, bytes allocated */ addnode(buf, size); return (buf); } void dlinit(void) { /* lock it so that multiple threads in application might not simultaniously * do a dlopen */ pthread_mutex_lock(&mt); if (dlh == NULL) { if ( (dlh = dlopen("libc.so", RTLD_NOW|RTLD_PARENT)) == NULL) { perror("dlopen: "); pthread_mutex_unlock(&mt); exit(1); } /* get pointers for malloc, calloc,... etc */ mptr = (void *(*)(size_t))dlsym(dlh, "malloc"); cptr = (void *(*)(size_t, size_t))dlsym(dlh, "calloc"); rptr = (void *(*)(void *, size_t))dlsym(dlh, "realloc"); vptr = (void *(*)(size_t))dlsym(dlh, "valloc"); malignptr = (void *(*)(size_t, size_t))dlsym(dlh, "memalign"); fptr = (void (*)(void *))dlsym(dlh, "free"); /* register signal handler*/ sigact.sa_handler = sighandler; if (sigaction(SIGNAL_USED, &sigact, NULL)) { perror("failed in registering signal"); } atexit(report); } pthread_mutex_unlock(&mt); } ... ... ... void sighandler(void) { pthread_t thr; /* create a new thread and dump current allocations which are not freed. */ pthread_create(&thr, NULL, reportallocs, NULL); pthread_detach(thr); } </plaintext> </div><br> <div class="entryfooter"> Jun 16 2005, 06:24:17 PM IST <a href="http://blogs.sun.com/popuri/entry/wrapper_library_to_track_memory" title="Permanent link to this weblog entry" class="entrypermalink">Permalink</a> <a href="http://blogs.sun.com/popuri/entry/wrapper_library_to_track_memory#comments" class="entrycommentslink">Comments [1]</a> </div> <br> <div class="trackbackUrl"> Trackback URL: http://blogs.sun.com/popuri/entry/wrapper_library_to_track_memory </div> <a name="comments"></a> <div class="comments" id="comments"> <div class="comments-head">Comments:</div> <br/> <a name="comment-1119531986000" id="comment-1119531986000"></a> <div class="comment odd" id="comment1"> Is it possible to get the source code for your library? The features sound really nice, should be much easier to use than libumem. <p class="comment-details"> Posted by <b>gorank</b> on June 23, 2005 at 06:36 PM IST <a href="http://blogs.sun.com/popuri/entry/wrapper_library_to_track_memory#comment-1119531986000" class="entrypermalink" title="comment permalink">#</a> </p> </div> </div> <div class="comments-form"> <div class="comments-head">Post a Comment:</div><br/> <form method="post" action="http://blogs.sun.com/popuri/entry/wrapper_library_to_track_memory" focus="name" name="form" onsubmit="fixURL(this); return validateComments(this)"> <!-- is this a post or a preview --> <input type="hidden" name="method" value="post" /> <table cellspacing="0" cellpadding="1" border="0" width="95%"> <tr><th>Name:</th> <td><input type="text" name="name" value="" size="50" maxlength="255" /></td> </tr> <tr><th>E-Mail:</th> <td><input type="text" name="email" value="" size="50" maxlength="255" /></td> </tr> <tr><th>URL:</th> <td><input type="text" name="url" value="" size="50" maxlength="255" /></td> </tr> <tr> <td></td> <td> <input type="checkbox" id="notify" name="notify" /> <label for="notify">Notify me by email of new comments</label> </td> </tr> <tr> <td></td> <td> <input type="checkbox" id="rememberInfo" name="rememberInfo" /> <label for="rememberInfo">Remember Information?</label> </td> </tr> </table> <br/> <table> <tr><th style="text-align: left">Your Comment:</th></tr> <tr> <td> <textarea name="content" cols="50" rows="10"></textarea><br /> <span class="comments-syntax-indicator"> HTML Syntax: <span class="disabled">NOT allowed</span> </span> </td> </tr> </table> <script type="text/javascript" src="/theme/scripts/clientSideInclude.js"></script> <div id="commentAuthenticator"></div> <table cellspacing="0" cellpadding="1" border="0" width="95%"> <tr> <td align="left" nowrap="nowrap"> <input type="button" name="post" value="&nbsp;Comment Preview&nbsp;" onClick="this.form.method.value='preview';this.form.submit()" /> <input type="submit" name="post" value="&nbsp;Post&nbsp;" /> </td> <td align="right"> <!-- <input type="button" value="&nbsp;Clear Info&nbsp;" /> --> </td> </tr> </table> </form> <script type="text/javascript" src="/theme/scripts/roller.js"></script> <script type="text/javascript"> clientSideInclude('commentAuthenticator', '/CommentAuthenticatorServlet'); var author = getCookie("commentAuthor"); var email = getCookie("commentEmail"); var url = getCookie("commentUrl"); // check each field - IE will render "null" if (author) { document.form.name.value = author; } if (email) { document.form.email.value = email; } if (url) { document.form.url.value = url; } if (author || email || url) { document.form.rememberInfo.checked = true; } function fixURL(theForm) { if (theForm.url.value != "" && theForm.url.value.indexOf("http://") == -1) { //prepend http:// theForm.url.value = "http://"+theForm.url.value; } saveUserInformation(theForm); } function saveUserInformation(theForm) { if (theForm.rememberInfo.checked) { rememberUser(theForm); } else { forgetUser(theForm); } } function validateComments(theForm) { if (theForm.content.value == "") { alert("Please enter a comment."); theForm.content.focus(); return false; } } </script> </div> <!-- Begin SiteCatalyst code version: G.5. --> <script type="text/javascript" language="JavaScript"> <!-- if(typeof s_channel=='undefined'){var s_channel="popuri";} //--></script> <script type="text/javascript" language="JavaScript" src="/omniture/s_code_remote.js"></script> <!-- End SiteCatalyst code version: G.5. --> </body> </html>