00001
00002
00003 #include "IgTools/IgTrace/src/IgTrace.h"
00004 #include "IgTools/IgHook/interface/IgHook.h"
00005 #include "IgTools/IgHook/interface/IgHookTrace.h"
00006 #include <cstdlib>
00007 #include <cstring>
00008 #include <cstdio>
00009 #include <pthread.h>
00010 #include <unistd.h>
00011
00012
00013
00014
00015
00016 class IgTraceMem
00017 {
00018 public:
00019 static void initialize (void);
00020 };
00021
00022
00023
00024
00025
00026
00027
00028 IGTRACE_DUAL_HOOK (1, void *, domalloc, _main, _libc,
00029 (size_t n), (n),
00030 "malloc", 0, "libc.so.6")
00031
00032
00033 static bool s_initialized = false;
00034
00035
00036
00037
00039 void
00040 IgTraceMem::initialize (void)
00041 {
00042 if (s_initialized) return;
00043 s_initialized = true;
00044
00045 const char *options = IgTrace::options ();
00046 bool enable = false;
00047
00048 while (options && *options)
00049 {
00050 while (*options == ' ' || *options == ',')
00051 ++options;
00052
00053 if (! strncmp (options, "mem", 3))
00054 {
00055 options += 3;
00056 enable = true;
00057 }
00058 else
00059 options++;
00060
00061 while (*options && *options != ',' && *options != ' ')
00062 options++;
00063 }
00064
00065 if (! enable)
00066 return;
00067
00068 if (! IgTrace::initialize ())
00069 return;
00070
00071 IgTrace::disable ();
00072 IgHook::hook (domalloc_hook_main.raw);
00073 #if __linux__
00074 if (domalloc_hook_main.raw.chain) IgHook::hook (domalloc_hook_libc.raw);
00075 #endif
00076
00077 IgTrace::debug ("Tracing memory allocations\n");
00078 IgTrace::enable ();
00079 }
00080
00082
00083 static void *
00084 domalloc (IgHook::SafeData<igtrace_domalloc_t> &hook, size_t size)
00085 {
00086 bool enabled = IgTrace::disable ();
00087 void *result = (*hook.chain) (size);
00088
00089 if (enabled)
00090 {
00091 void *stack [800];
00092 int depth = IgHookTrace::stacktrace (stack, sizeof (stack)/sizeof(stack[0]));
00093
00094
00095 if (IgTrace::filter (0, stack, depth))
00096 {
00097 char buf [1024];
00098 write (2, buf, sprintf (buf,
00099 "*** MALLOC %ld bytes => %p, by %.500s [thread %lu pid %ld]\n",
00100 (unsigned long) size, result, IgTrace::program(),
00101 (unsigned long) pthread_self (), (long) getpid ()));
00102 }
00103 }
00104
00105 IgTrace::enable ();
00106 return result;
00107 }
00108
00110 static bool autoboot = (IgTraceMem::initialize (), true);