5656#include <signal.h>
5757#include <errno.h>
5858#include <malloc.h>
59+ #include <time.h>
5960
6061#ifdef HAVE_UNWIND
62+ /* speedup unwinding */
63+ #define UNW_LOCAL_ONLY 1
64+
6165#include <libunwind.h>
6266#endif
6367
6872
6973/* config */
7074#ifdef HAVE_UNWIND
75+ #ifdef HAVE_UNWIND_DETAIL
7176#define LOG_BUFSIZE (128 + (256 * LOG_MALLOC_BACKTRACE_COUNT))
7277#else
78+ #define LOG_BUFSIZE (128 + (32 * LOG_MALLOC_BACKTRACE_COUNT))
79+ #endif
80+ #else
7381#define LOG_BUFSIZE 128
7482#endif
7583
@@ -171,7 +179,8 @@ static void *__init_lib(void)
171179 DL_RESOLVE (posix_memalign );
172180 DL_RESOLVE (valloc );
173181
174- //TODO: call backtrace here to init itself
182+ /* clock */
183+ g_ctx .clock_start = clock ();
175184
176185 /* post-init status */
177186 if (!g_ctx .memlog_disabled )
@@ -180,6 +189,9 @@ static void *__init_lib(void)
180189 char path [256 ];
181190 char buf [LOG_BUFSIZE + sizeof (path )];
182191
192+ s = snprintf (buf , sizeof (buf ), "# CLOCK-START %lu\n" , g_ctx .clock_start );
193+ w = write (g_ctx .memlog_fd , buf , s );
194+
183195 s = snprintf (buf , sizeof (buf ), "# PID %u\n" , getpid ());
184196 w = write (g_ctx .memlog_fd , buf , s );
185197
@@ -207,6 +219,7 @@ static void *__init_lib(void)
207219 g_ctx .stat .free );
208220 w = write (g_ctx .memlog_fd , buf , s );
209221
222+
210223 /* auto-disable trace if file is not open */
211224 if (w == -1 && errno == EBADF )
212225 g_ctx .memlog_disabled = true;
@@ -226,6 +239,8 @@ static void __attribute__ ((constructor))log_malloc2_init(void)
226239
227240static void __fini_lib (void )
228241{
242+ clock_t clck = clock ();
243+
229244 /* check already finalized */
230245 if (!__sync_bool_compare_and_swap (& g_ctx .init_done ,
231246 LOG_MALLOC_INIT_DONE , LOG_MALLOC_FINI_DONE ))
@@ -247,6 +262,12 @@ static void __fini_lib(void)
247262
248263 /* maps out here, because dynamic libs could by mapped during run */
249264 copyfile (maps_head , sizeof (maps_head ) - 1 , g_maps_path , g_ctx .memlog_fd );
265+
266+ s = snprintf (buf , sizeof (buf ), "# CLOCK-END %lu\n" , clck );
267+ w = write (g_ctx .memlog_fd , buf , s );
268+
269+ s = snprintf (buf , sizeof (buf ), "# CLOCK-DIFF %lu\n" , clck - g_ctx .clock_start );
270+ w = write (g_ctx .memlog_fd , buf , s );
250271 }
251272
252273 if (g_ctx .statm_fd != -1 )
@@ -266,6 +287,33 @@ static void __attribute__ ((destructor))log_malloc2_fini(void)
266287/*
267288 * INTERNAL FUNCTIONS
268289 */
290+ static inline size_t int2hex (unsigned long int num , char * str , size_t max_size )
291+ {
292+ size_t len = 0 ;
293+ const static char hex [] = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' ,
294+ '8' , '9' ,'a' , 'b' , 'c' , 'd' , 'e' , 'f' };
295+
296+ do
297+ {
298+ str [len ++ ] = hex [ num & 0xf ];
299+ num >>= 4 ;
300+ } while (num != 0 );
301+
302+ unsigned int ii = 0 ;
303+ for (ii = 0 ; ii < (len / 2 ); ii ++ )
304+ {
305+ const unsigned int pos = len - ii - 1 ;
306+ const char w = str [ii ];
307+
308+ str [ii ] = str [pos ];
309+ str [pos ] = w ;
310+ }
311+ str [len ] = '\0' ;
312+
313+ return len ;
314+ }
315+
316+
269317static inline void log_trace (char * str , size_t len , size_t max_size , int print_stack )
270318{
271319 int w ;
@@ -280,9 +328,12 @@ static inline void log_trace(char *str, size_t len, size_t max_size, int print_s
280328 unw_cursor_t cursor ;
281329 int unwind_count = 0 ;
282330
283- unwind = (unw_getcontext (& uc ) == 0 );
284- if (unwind )
285- unwind = (unw_init_local (& cursor , & uc ) == 0 );
331+ if (print_stack )
332+ {
333+ unwind = (unw_getcontext (& uc ) == 0 );
334+ if (unwind )
335+ unwind = (unw_init_local (& cursor , & uc ) == 0 );
336+ }
286337#else
287338#ifdef HAVE_BACKTRACE
288339 int nptrs = 0 ;
@@ -304,15 +355,18 @@ static inline void log_trace(char *str, size_t len, size_t max_size, int print_s
304355 }
305356
306357#ifdef HAVE_UNWIND
307- while (unwind && unwind_count < LOG_MALLOC_BACKTRACE_COUNT
308- && unw_step (& cursor ) > 0 )
358+ while (print_stack && unwind && unwind_count < LOG_MALLOC_BACKTRACE_COUNT
359+ && unw_step (& cursor ) > 0
360+ && max_size - len > (16 + 5 ))
309361 {
310362 unw_word_t ip = 0 ;
311363 unw_word_t offp = 0 ;
312364 size_t len_start = len ;
313365
314366 unw_get_reg (& cursor , UNW_REG_IP , & ip );
315367
368+ #ifdef HAVE_UNWIND_DETAIL
369+ /* this harms performance */
316370 str [len ++ ] = '*' ;
317371 str [len ++ ] = '(' ;
318372 if (unw_get_proc_name (& cursor , & str [len ], max_size - len - 1 , & offp ) == 0 )
@@ -323,8 +377,13 @@ static inline void log_trace(char *str, size_t len, size_t max_size, int print_s
323377 }
324378 else
325379 len += -2 ;
380+ #endif
326381
327- len += snprintf (& str [len ], max_size - len - 1 , "[0x%lx]" , ip );
382+ str [len ++ ] = '[' ;
383+ str [len ++ ] = '0' ;
384+ str [len ++ ] = 'x' ;
385+ len += int2hex (ip , & str [len ], max_size - len - 1 ); // max 16 chars
386+ str [len ++ ] = ']' ;
328387 str [len ++ ] = '\n' ;
329388
330389 unwind_count ++ ;
0 commit comments