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();
+}