Index: memintercept.c =================================================================== RCS file: /cvs/gnome/memprof/memintercept.c,v retrieving revision 1.18 diff -u -p -r1.18 memintercept.c --- memintercept.c 19 Aug 2002 18:26:46 -0000 1.18 +++ memintercept.c 24 Aug 2002 21:13:59 -0000 @@ -38,6 +38,9 @@ #include #include +#include +#include + /* The code in this file is written to work for threaded operation without * any reference to the thread library in operation. There are only * two places where any interaction between threads is necessary - @@ -334,6 +337,7 @@ write_stack (int n_frames, errno = old_errno; } +#if 0 static void * do_malloc (size_t size, int to_skip) { @@ -495,6 +499,7 @@ free (void *ptr) { do_free (ptr); } +#endif int __fork (void) @@ -670,6 +675,61 @@ _exit (int status) (*old__exit) (status); } +#define TIMER_TYPE ITIMER_PROF +static int profile_interval = 10; + +static void +start_timer (void) +{ + struct itimerval it, tem; + it.it_interval.tv_usec = 0; + it.it_interval.tv_sec = 0; + it.it_value.tv_usec = profile_interval % 1000000; + it.it_value.tv_sec = profile_interval / 1000000; + setitimer (TIMER_TYPE, &it, &tem); +} + +/* XXX hmm.. */ +#define SIGHANDLER_FRAMES 2 + +static void +#if defined (__linux__) && defined (__i386__) +sigprof_handler (int unused, struct sigcontext ctx) +#else +sigprof_handler (int unused) +#endif +{ + int saved_errno = errno; + MIInfo info; + + info.alloc.operation = MI_MALLOC; + info.alloc.old_ptr = NULL; + info.alloc.new_ptr = (void *) seqno; + info.alloc.size = 1; + +#if defined (__linux__) && defined (__i386__) + mi_call_with_signal_backtrace ((void *)ctx.eip, (void *)ctx.ebp, (void *)ctx.esp, + write_stack, &info); +#else + mi_call_with_backtrace (SIGHANDLER_FRAMES, saved_pc, write_stack, &info); +#endif + + start_timer (); + errno = saved_errno; +} + +static void +init_sighandler (void) +{ + struct sigaction sa; + sa.sa_handler = (void (*)(int))sigprof_handler; + sigemptyset (&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sigaction (TIMER_TYPE == ITIMER_PROF ? SIGPROF + : TIMER_TYPE == ITIMER_VIRTUAL ? SIGVTALRM + : SIGALRM, &sa, 0); +} + /* This is not, strictly speaking, necessary, since we'll initialize * upon demand, but it ensures sure that we always initialize * as promptly as possible. @@ -680,4 +740,11 @@ static void construct () { if (initialized <= 0) initialize (); + + if (!socket_path) + memprof_init (); + + tracing = 0; + init_sighandler (); + start_timer (); }