Only close stdin/stdout/stderr for debug malloc.

The debug malloc code unconditionally closes stdin/stdout/stderr,
which means that other atexit functions cannot use them. Only
close these if there is a debug malloc final function to call.

This doesn't appear to be a problem on most normal applications or the
atexit_exit bionic unit test would be failing. However, if you
enable stat dumping in jemalloc, nothing prints. Most likely trying
to add an atexit function from within libc is causing that atexit
to run after the debug malloc atexit function.

Change-Id: I963720d4ccaaa511e44af07a7461f17eb3f84e8e
This commit is contained in:
Christopher Ferris 2015-09-03 15:01:59 -07:00
parent b423ffa6c2
commit efc134dba3

View File

@ -486,18 +486,19 @@ static void malloc_init_impl() {
}
static void malloc_fini_impl() {
// Our BSD stdio implementation doesn't close the standard streams, it only flushes them.
// And it doesn't do that until its atexit handler is run, and we run first!
// It's great that other unclosed FILE*s show up as malloc leaks, but we need to manually
// clean up the standard streams ourselves.
fclose(stdin);
fclose(stdout);
fclose(stderr);
if (libc_malloc_impl_handle != NULL) {
MallocDebugFini malloc_debug_finalize =
reinterpret_cast<MallocDebugFini>(dlsym(libc_malloc_impl_handle, "malloc_debug_finalize"));
if (malloc_debug_finalize != NULL) {
// Our BSD stdio implementation doesn't close the standard streams,
// it only flushes them. And it doesn't do that until its atexit
// handler is run, and we run first! It's great that other unclosed
// FILE*s show up as malloc leaks, but we need to manually clean up
// the standard streams ourselves.
fclose(stdin);
fclose(stdout);
fclose(stderr);
malloc_debug_finalize(g_malloc_debug_level);
}
}