Fix the duplication in the debugging code.

We had two copies of the backtrace code, and two copies of the
libcorkscrew /proc/pid/maps code. This patch gets us down to one.

We also had hacks so we could log in the malloc debugging code.
This patch pulls the non-allocating "printf" code out of the
dynamic linker so everyone can share.

This patch also makes the leak diagnostics easier to read, and
makes it possible to paste them directly into the 'stack' tool (by
using relative PCs).

This patch also fixes the stdio standard stream leak that was
causing a leak warning every time tf_daemon ran.

Bug: 7291287
Change-Id: I66e4083ac2c5606c8d2737cb45c8ac8a32c7cfe8
diff --git a/libc/bionic/malloc_debug_common.cpp b/libc/bionic/malloc_debug_common.cpp
index 624a40e..bba0472 100644
--- a/libc/bionic/malloc_debug_common.cpp
+++ b/libc/bionic/malloc_debug_common.cpp
@@ -294,8 +294,8 @@
 unsigned int malloc_double_free_backlog;
 
 static void InitMalloc(MallocDebug* table, int debug_level, const char* prefix) {
-  __libc_android_log_print(ANDROID_LOG_INFO, "libc", "%s: using libc.debug.malloc %d (%s)\n",
-                           __progname, debug_level, prefix);
+  __libc_format_log(ANDROID_LOG_INFO, "libc", "%s: using libc.debug.malloc %d (%s)\n",
+                    __progname, debug_level, prefix);
 
   char symbol[128];
 
@@ -429,7 +429,7 @@
         dlclose(libc_malloc_impl_handle);
         return;
     }
-    if (malloc_debug_initialize()) {
+    if (malloc_debug_initialize() == -1) {
         dlclose(libc_malloc_impl_handle);
         return;
     }
@@ -487,11 +487,19 @@
 }
 
 static void malloc_fini_impl() {
-    if (libc_malloc_impl_handle) {
+    // Our BSD stdio implementation doesn't close the standard streams, it only flushes them.
+    // And it doesn't do that until its atexit handler (_cleanup) 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) {
+        if (malloc_debug_finalize != NULL) {
             malloc_debug_finalize();
         }
     }