aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPino Toscano <toscano.pino@tiscali.it>2012-11-19 20:01:00 +0100
committerPino Toscano <toscano.pino@tiscali.it>2012-11-19 20:01:00 +0100
commite19af3803be804f2737788e62d243e425bb03011 (patch)
tree725b6d3e1e96ddea102a88887a5632b380bd2c71
parent942caa165645cf1cd0d65f8ecd4b4cbdfa32a34a (diff)
downloadglibc-e19af3803be804f2737788e62d243e425bb03011.zip
glibc-e19af3803be804f2737788e62d243e425bb03011.tar.gz
glibc-e19af3803be804f2737788e62d243e425bb03011.tar.bz2
muntrace: reset file and hooks before finalizing the stream
fclose will call free, invoking its hook, then fprintf which would indirectly try to allocate a buffer, and this can cause malloc to be used (thus its hook to be invoked) if libio uses malloc instead of mmap; given any malloc/free hook locks the internal lock, this leads to a deadlock. To prevent this hook roundtrip at muntrace, first unset MALLSTREAM and the hooks, and only after that close the trace file.
-rw-r--r--ChangeLog3
-rw-r--r--malloc/mtrace.c9
2 files changed, 10 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index fbac1c5..1031d4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2012-11-19 Pino Toscano <toscano.pino@tiscali.it>
+ * malloc/mtrace.c (muntrace): Reset MALLSTREAM and the hooks before
+ finalizing MALLSTREAM.
+
* sysdeps/mach/hurd/syncfs.c: New file.
2012-11-19 Siddhesh Poyarekar <siddhesh@redhat.com>
diff --git a/malloc/mtrace.c b/malloc/mtrace.c
index d7a032a..3f02c71 100644
--- a/malloc/mtrace.c
+++ b/malloc/mtrace.c
@@ -364,11 +364,16 @@ muntrace ()
if (mallstream == NULL)
return;
- fprintf (mallstream, "= End\n");
- fclose (mallstream);
+ /* Do the reverse of what done in mtrace: first reset the hooks and
+ MALLSTREAM, and only after that write the trailer and close the
+ file. */
+ FILE *f = mallstream;
mallstream = NULL;
__free_hook = tr_old_free_hook;
__malloc_hook = tr_old_malloc_hook;
__realloc_hook = tr_old_realloc_hook;
__memalign_hook = tr_old_memalign_hook;
+
+ fprintf (f, "= End\n");
+ fclose (f);
}