ART: Dump proc/maps on mem_map_test failure

On any fatal failure, also dump the process maps to the log.
Implemented through a gtest TestListener.

Bug: 118408378
Test: m test-art-host
Test: manual (add always-fail ASSERT)
Change-Id: I05b1f19680f8ab020aea89e7429757833e307fd5
diff --git a/libartbase/base/mem_map_test.cc b/libartbase/base/mem_map_test.cc
index 5815cf9..813d90d 100644
--- a/libartbase/base/mem_map_test.cc
+++ b/libartbase/base/mem_map_test.cc
@@ -21,8 +21,9 @@
 #include <memory>
 #include <random>
 
-#include "base/common_art_test.h"
+#include "common_art_test.h"
 #include "common_runtime_test.h"  // For TEST_DISABLED_FOR_MIPS
+#include "logging.h"
 #include "memory_tool.h"
 #include "unix_file/fd_file.h"
 
@@ -874,3 +875,30 @@
 }
 
 }  // namespace art
+
+namespace {
+
+class DumpMapsOnFailListener : public testing::EmptyTestEventListener {
+  void OnTestPartResult(const testing::TestPartResult& result) override {
+    switch (result.type()) {
+      case testing::TestPartResult::kFatalFailure:
+        art::PrintFileToLog("/proc/self/maps", android::base::LogSeverity::ERROR);
+        break;
+
+      // TODO: Could consider logging on EXPECT failures.
+      case testing::TestPartResult::kNonFatalFailure:
+      case testing::TestPartResult::kSuccess:
+        break;
+    }
+  }
+};
+
+}  // namespace
+
+// Inject our listener into the test runner.
+extern "C"
+__attribute__((visibility("default"))) __attribute__((used))
+void ArtTestGlobalInit() {
+  LOG(ERROR) << "Installing listener";
+  testing::UnitTest::GetInstance()->listeners().Append(new DumpMapsOnFailListener());
+}
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index be39631..cfc0d28 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -59,20 +59,6 @@
 #include "thread.h"
 #include "well_known_classes.h"
 
-int main(int argc, char **argv) {
-  // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
-  // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
-  // everything else. In case you want to see all messages, comment out the line.
-  setenv("ANDROID_LOG_TAGS", "*:e", 1);
-
-  art::Locks::Init();
-  art::InitLogging(argv, art::Runtime::Abort);
-  art::MemMap::Init();
-  LOG(INFO) << "Running main() from common_runtime_test.cc...";
-  testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
-}
-
 namespace art {
 
 using android::base::StringPrintf;
@@ -420,3 +406,26 @@
 }
 
 }  // namespace art
+
+// Allow other test code to run global initialization/configuration before
+// gtest infra takes over.
+extern "C"
+__attribute__((visibility("default"))) __attribute__((weak))
+void ArtTestGlobalInit() {
+  LOG(ERROR) << "ArtTestGlobalInit in common_runtime_test";
+}
+
+int main(int argc, char **argv) {
+  // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
+  // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
+  // everything else. In case you want to see all messages, comment out the line.
+  setenv("ANDROID_LOG_TAGS", "*:e", 1);
+
+  art::Locks::Init();
+  art::InitLogging(argv, art::Runtime::Abort);
+  art::MemMap::Init();
+  LOG(INFO) << "Running main() from common_runtime_test.cc...";
+  testing::InitGoogleTest(&argc, argv);
+  ArtTestGlobalInit();
+  return RUN_ALL_TESTS();
+}