Re: Profile disappears when process ends
- From: Owen Taylor <otaylor redhat com>
- To: Harry Tily <hal sfc keio ac jp>
- Cc: memprof-list gnome org
- Subject: Re: Profile disappears when process ends
- Date: Sat, 20 Sep 2003 10:54:56 -0400
On Sat, 2003-09-20 at 08:55, Owen Taylor wrote:
> On Sat, 2003-09-20 at 00:33, Harry Tily wrote:
> > Hi
> >
> > I'm trying to figure out how to use memprof (isn't there anyone on this
> > list who can use it and has time to write a very brief manual?) I've
> > managed to get my process running and generate its profile and leak
> > information, but as soon as the process ends, all that data vanishes
> > again. This only gives me a few seconds to look at the output and try to
> > work out what's happening. How do I keep the information on screen?
>
> With recent versions of glibc, the code in memprof to keep the child
> from exiting stopped working. I haven't tracked the problem down ...
> what you can do is simply put a sleep(3600) at the end of your
> main routine.
Just put a fix/workaround for this into CVS:
Sat Sep 20 10:52:06 2003 Owen Taylor <otaylor redhat com>
* intercept.c): Switch to atexit() as the primary means
of intercepting exiting. It isn't as good as interposing _exit,
but interposing _exit doesn't work with newer versions of
GNU libc.
Regards,
Owen
Index: intercept.c
===================================================================
RCS file: /cvs/gnome/memprof/intercept.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- intercept.c 5 Sep 2002 19:16:38 -0000 1.1
+++ intercept.c 20 Sep 2003 14:54:16 -0000 1.2
@@ -55,6 +55,7 @@ typedef struct {
static void new_process (ThreadInfo *thread,
pid_t old_pid,
MIOperation operation);
+static void atexit_trap (void);
static int (*old_execve) (const char *filename,
char *const argv[],
@@ -76,7 +77,7 @@ static ThreadInfo threads[MAX_THREADS];
static char *socket_path = NULL;
static unsigned int seqno = 0;
-#undef ENABLE_DEBUG
+#define ENABLE_DEBUG
#ifdef ENABLE_DEBUG
#define MI_DEBUG(arg) mi_debug arg
@@ -170,6 +171,8 @@ initialize ()
old_clone = dlsym(RTLD_NEXT, "__clone");
old__exit = dlsym(RTLD_NEXT, "_exit");
+ atexit (atexit_trap);
+
mi_init ();
initialized = 1;
}
@@ -470,42 +473,64 @@ int clone (int (*fn) (void *arg),
return __clone (fn, child_stack, flags, arg);
}
+static void
+exit_wait (void)
+{
+ MIInfo info;
+ ThreadInfo *thread;
+ int count;
+ char response;
+ info.any.operation = MI_EXIT;
+ info.any.seqno = seqno++;
+ info.any.pid = getpid();
+
+ mi_stop ();
+
+ thread = find_thread (info.any.pid);
+
+ if (mi_write (thread->outfd, &info, sizeof (MIInfo)))
+ /* Wait for a response before really exiting
+ */
+ while (1) {
+ count = read (thread->outfd, &response, 1);
+ if (count >= 0 || errno != EINTR)
+ break;
+ }
+
+ close (thread->outfd);
+ thread->pid = 0;
+ release_thread (thread);
+}
+
+/* Because _exit() isn't interposable in recent versions of
+ * GNU libc, we can't depend on this, and instead use the less-good
+ * atexit_trap() below. But we leave this here just in case we
+ * are using an old version of libc where _exit() is interposable,
+ * so we can trap a wider range of exit conditions
+ */
void
_exit (int status)
{
if (initialized <= 0)
- abort_unitialized ("exit");
+ abort_unitialized ("_exit");
- MI_DEBUG (("Exiting\n"));
+ MI_DEBUG (("_Exiting\n"));
if (tracing) {
- MIInfo info;
- ThreadInfo *thread;
- int count;
- char response;
- info.any.operation = MI_EXIT;
- info.any.seqno = seqno++;
- info.any.pid = getpid();
-
- mi_stop ();
-
- thread = find_thread (info.any.pid);
-
- if (mi_write (thread->outfd, &info, sizeof (MIInfo)))
- /* Wait for a response before really exiting
- */
- while (1) {
- count = read (thread->outfd, &response, 1);
- if (count >= 0 || errno != EINTR)
- break;
- }
-
- close (thread->outfd);
- thread->pid = 0;
- release_thread (thread);
+ exit_wait ();
+ tracing = 0;
}
(*old__exit) (status);
+}
+
+static void
+atexit_trap (void)
+{
+ if (tracing) {
+ exit_wait ();
+ tracing = 0;
+ }
}
static void construct () __attribute__ ((constructor));
[
Date Prev][Date Next] [
Thread Prev][Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]