Add option to force memunreachable check.

The new option is named check_unreachable_on_signal. It is meant
to duplicate dumpsys meminfo --unreachable <PID> for non-java
processes. When enabled, a user can send a signal to a process
which will trigger the unreachable check on the next allocation
call.

Added new unit tests.

Test: New unit tests pass.
Test: Enabled for the entire system, then dumped on the netd
Test: process and also system_server.
Change-Id: I73561b408a947a11ce21a211b065d59fcc39097b
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index d608f5d..35cda83 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -53,11 +53,12 @@
 
 #include "Config.h"
 #include "DebugData.h"
+#include "Unreachable.h"
+#include "UnwindBacktrace.h"
 #include "backtrace.h"
 #include "debug_disable.h"
 #include "debug_log.h"
 #include "malloc_debug.h"
-#include "UnwindBacktrace.h"
 
 // ------------------------------------------------------------------------
 // Global Data
@@ -315,7 +316,7 @@
   }
 
   DebugData* debug = new DebugData();
-  if (!debug->Initialize(options)) {
+  if (!debug->Initialize(options) || !Unreachable::Initialize(debug->config())) {
     delete debug;
     DebugDisableFinalize();
     return false;
@@ -402,6 +403,8 @@
 }
 
 size_t debug_malloc_usable_size(void* pointer) {
+  Unreachable::CheckIfRequested(g_debug->config());
+
   if (DebugCallsDisabled() || pointer == nullptr) {
     return g_dispatch->malloc_usable_size(pointer);
   }
@@ -467,6 +470,8 @@
 }
 
 void* debug_malloc(size_t size) {
+  Unreachable::CheckIfRequested(g_debug->config());
+
   if (DebugCallsDisabled()) {
     return g_dispatch->malloc(size);
   }
@@ -544,6 +549,8 @@
 }
 
 void debug_free(void* pointer) {
+  Unreachable::CheckIfRequested(g_debug->config());
+
   if (DebugCallsDisabled() || pointer == nullptr) {
     return g_dispatch->free(pointer);
   }
@@ -563,6 +570,8 @@
 }
 
 void* debug_memalign(size_t alignment, size_t bytes) {
+  Unreachable::CheckIfRequested(g_debug->config());
+
   if (DebugCallsDisabled()) {
     return g_dispatch->memalign(alignment, bytes);
   }
@@ -643,6 +652,8 @@
 }
 
 void* debug_realloc(void* pointer, size_t bytes) {
+  Unreachable::CheckIfRequested(g_debug->config());
+
   if (DebugCallsDisabled()) {
     return g_dispatch->realloc(pointer, bytes);
   }
@@ -763,6 +774,8 @@
 }
 
 void* debug_calloc(size_t nmemb, size_t bytes) {
+  Unreachable::CheckIfRequested(g_debug->config());
+
   if (DebugCallsDisabled()) {
     return g_dispatch->calloc(nmemb, bytes);
   }
@@ -862,6 +875,8 @@
 }
 
 void* debug_aligned_alloc(size_t alignment, size_t size) {
+  Unreachable::CheckIfRequested(g_debug->config());
+
   if (DebugCallsDisabled()) {
     return g_dispatch->aligned_alloc(alignment, size);
   }
@@ -873,6 +888,8 @@
 }
 
 int debug_posix_memalign(void** memptr, size_t alignment, size_t size) {
+  Unreachable::CheckIfRequested(g_debug->config());
+
   if (DebugCallsDisabled()) {
     return g_dispatch->posix_memalign(memptr, alignment, size);
   }
@@ -934,6 +951,8 @@
 
 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
 void* debug_pvalloc(size_t bytes) {
+  Unreachable::CheckIfRequested(g_debug->config());
+
   if (DebugCallsDisabled()) {
     return g_dispatch->pvalloc(bytes);
   }
@@ -949,6 +968,8 @@
 }
 
 void* debug_valloc(size_t size) {
+  Unreachable::CheckIfRequested(g_debug->config());
+
   if (DebugCallsDisabled()) {
     return g_dispatch->valloc(size);
   }