Merge "Remove the KSM hack in mmap()."
diff --git a/libc/bionic/heap_tagging.cpp b/libc/bionic/heap_tagging.cpp
index f84ba7b..9b67d85 100644
--- a/libc/bionic/heap_tagging.cpp
+++ b/libc/bionic/heap_tagging.cpp
@@ -92,11 +92,6 @@
 pthread_mutex_t g_heap_tagging_lock = PTHREAD_MUTEX_INITIALIZER;
 
 // Requires `g_heap_tagging_lock` to be held.
-HeapTaggingLevel GetHeapTaggingLevel() {
-  return heap_tagging_level;
-}
-
-// Requires `g_heap_tagging_lock` to be held.
 bool SetHeapTaggingLevel(HeapTaggingLevel tag_level) {
   if (tag_level == heap_tagging_level) {
     return true;
diff --git a/libc/bionic/heap_tagging.h b/libc/bionic/heap_tagging.h
index 110b6ed..a3588b8 100644
--- a/libc/bionic/heap_tagging.h
+++ b/libc/bionic/heap_tagging.h
@@ -40,7 +40,6 @@
 // useful for RAII on this lock.
 extern pthread_mutex_t g_heap_tagging_lock;
 
-// These functions can be called in a multithreaded context, and thus should
+// This function can be called in a multithreaded context, and thus should
 // only be called when holding the `g_heap_tagging_lock`.
 bool SetHeapTaggingLevel(HeapTaggingLevel level);
-HeapTaggingLevel GetHeapTaggingLevel();
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index 344f9a7..e7a157e 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -122,6 +122,7 @@
 cc_test {
     name: "malloc_debug_unit_tests",
     test_suites: ["device-tests"],
+    isolated: true,
 
     srcs: [
         "tests/backtrace_fake.cpp",
@@ -181,7 +182,6 @@
 
     shared_libs: [
         "libbase",
-        "libbacktrace",
         "liblog",
         "libunwindstack",
     ],
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index eaa0eb7..d062086 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -149,14 +149,14 @@
     if (num_frames == 0) {
       return kBacktraceEmptyIndex;
     }
+    frames.resize(num_frames);
   }
 
-  FrameKeyType key{.num_frames = num_frames, .frames = frames.data()};
+  FrameKeyType key{.num_frames = frames.size(), .frames = frames.data()};
   size_t hash_index;
   std::lock_guard<std::mutex> frame_guard(frame_mutex_);
   auto entry = key_to_index_.find(key);
   if (entry == key_to_index_.end()) {
-    frames.resize(num_frames);
     hash_index = cur_hash_index_++;
     key.frames = frames.data();
     key_to_index_.emplace(key, hash_index);
diff --git a/libc/malloc_debug/UnwindBacktrace.cpp b/libc/malloc_debug/UnwindBacktrace.cpp
index f6c3e69..c892a39 100644
--- a/libc/malloc_debug/UnwindBacktrace.cpp
+++ b/libc/malloc_debug/UnwindBacktrace.cpp
@@ -36,11 +36,7 @@
 #include <vector>
 
 #include <android-base/stringprintf.h>
-#include <unwindstack/MapInfo.h>
-#include <unwindstack/Maps.h>
-#include <unwindstack/Memory.h>
-#include <unwindstack/Regs.h>
-#include <unwindstack/RegsGetLocal.h>
+#include <unwindstack/AndroidUnwinder.h>
 #include <unwindstack/Unwinder.h>
 
 #include "UnwindBacktrace.h"
@@ -54,51 +50,22 @@
 
 extern "C" char* __cxa_demangle(const char*, char*, size_t*, int*);
 
-static pthread_once_t g_setup_once = PTHREAD_ONCE_INIT;
-
-static unwindstack::LocalUpdatableMaps* g_maps;
-static std::shared_ptr<unwindstack::Memory> g_process_memory;
-#if defined(__LP64__)
-static std::vector<std::string> g_skip_libraries{"/system/lib64/libunwindstack.so",
-                                                 "/system/lib64/libc_malloc_debug.so"};
-#else
-static std::vector<std::string> g_skip_libraries{"/system/lib/libunwindstack.so",
-                                                 "/system/lib/libc_malloc_debug.so"};
-#endif
-
-static void Setup() {
-  g_maps = new unwindstack::LocalUpdatableMaps;
-  if (!g_maps->Parse()) {
-    delete g_maps;
-    g_maps = nullptr;
-  }
-
-  g_process_memory = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid());
-}
-
 bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* frame_info,
             size_t max_frames) {
-  pthread_once(&g_setup_once, Setup);
-
-  if (g_maps == nullptr) {
-    return false;
-  }
-
-  std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal());
-  unwindstack::RegsGetLocal(regs.get());
-  unwindstack::Unwinder unwinder(max_frames, g_maps, regs.get(), g_process_memory);
-  unwinder.Unwind(&g_skip_libraries);
-  if (unwinder.NumFrames() == 0) {
+  [[clang::no_destroy]] static unwindstack::AndroidLocalUnwinder unwinder(
+      std::vector<std::string>{"libc_malloc_debug.so"});
+  unwindstack::AndroidUnwinderData data(max_frames);
+  if (!unwinder.Unwind(data)) {
     frames->clear();
     frame_info->clear();
     return false;
   }
-  *frame_info = unwinder.ConsumeFrames();
 
-  frames->resize(frame_info->size());
-  for (size_t i = 0; i < frame_info->size(); i++) {
-    frames->at(i) = frame_info->at(i).pc;
+  frames->resize(data.frames.size());
+  for (const auto& frame : data.frames) {
+    frames->at(frame.num) = frame.pc;
   }
+  *frame_info = std::move(data.frames);
   return true;
 }
 
diff --git a/libc/malloc_debug/UnwindBacktrace.h b/libc/malloc_debug/UnwindBacktrace.h
index 7f89907..091865e 100644
--- a/libc/malloc_debug/UnwindBacktrace.h
+++ b/libc/malloc_debug/UnwindBacktrace.h
@@ -30,10 +30,8 @@
 
 #include <stdint.h>
 
-#include <string>
 #include <vector>
 
-#include <unwindstack/MapInfo.h>
 #include <unwindstack/Unwinder.h>
 
 bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* info,
diff --git a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
index 92679e4..aee2572 100644
--- a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
@@ -52,8 +52,7 @@
 #include <thread>
 #include <vector>
 
-#include <backtrace/Backtrace.h>
-#include <backtrace/BacktraceMap.h>
+#include <unwindstack/AndroidUnwinder.h>
 
 #include <bionic/malloc.h>
 #include <tests/utils.h>
@@ -452,12 +451,19 @@
   static constexpr size_t kMaxRetries = 3;
 };
 
-TEST(MallocTests, DISABLED_smoke) {}
+TEST(MallocTests, DISABLED_smoke) {
+  void* ptr = malloc(128);
+  free(ptr);
+}
 
 TEST_F(MallocDebugSystemTest, smoke) {
   Exec("MallocTests.DISABLED_smoke", "verbose backtrace");
 }
 
+TEST_F(MallocDebugSystemTest, backtrace_full_smoke) {
+  Exec("MallocTests.DISABLED_smoke", "verbose backtrace backtrace_full");
+}
+
 static void SetAllocationLimit() {
   // Set to a large value, this is only to enable the limit code and
   // verify that malloc debug is still called properly.
@@ -763,13 +769,14 @@
   }
 
   static constexpr size_t kNumUnwinds = 1000;
+  unwindstack::AndroidLocalUnwinder unwinder;
   for (size_t i = 0; i < kNumUnwinds; i++) {
-    std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), tid));
     // Only verify that there is at least one frame in the unwind.
     // This is not a test of the unwinder and clang for arm seems to
     // produces an increasing number of code that does not have unwind
     // information.
-    ASSERT_TRUE(backtrace->Unwind(0)) << "Failed on unwind " << i;
+    unwindstack::AndroidUnwinderData data;
+    ASSERT_TRUE(unwinder.Unwind(data)) << "Failed on unwind " << i;
   }
   running = false;
   thread.join();
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index ff743ac..b97e638 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -83,6 +83,14 @@
 
 __END_DECLS
 
+// Change the slow threshold since some tests take more than 2 seconds.
+extern "C" bool GetInitialArgs(const char*** args, size_t* num_args) {
+  static const char* initial_args[] = {"--slow_threshold_ms=5000"};
+  *args = initial_args;
+  *num_args = 1;
+  return true;
+}
+
 constexpr char DIVIDER[] =
     "6 malloc_debug *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n";
 
@@ -90,7 +98,7 @@
   return __BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
 }
 
-static constexpr const char RECORD_ALLOCS_FILE[] = "/data/local/tmp/record_allocs.txt";
+static constexpr const char RECORD_ALLOCS_FILE[] = "/data/local/tmp/record_allocs";
 
 static constexpr const char BACKTRACE_DUMP_PREFIX[] = "/data/local/tmp/backtrace_heap";
 
@@ -100,8 +108,10 @@
     initialized = false;
     resetLogs();
     backtrace_fake_clear_all();
-    // Delete the record data file if it exists.
-    unlink(RECORD_ALLOCS_FILE);
+    if (!record_filename.empty()) {
+      // Delete the record data file if it exists.
+      unlink(record_filename.c_str());
+    }
   }
 
   void TearDown() override {
@@ -116,6 +126,13 @@
     initialized = true;
   }
 
+  void InitRecordAllocs(const char* options) {
+    record_filename = android::base::StringPrintf("%s.%d.txt", RECORD_ALLOCS_FILE, getpid());
+    std::string init(options);
+    init += android::base::StringPrintf(" record_allocs_file=%s", record_filename.c_str());
+    Init(init.c_str());
+  }
+
   void BacktraceDumpOnSignal(bool trigger_with_alloc);
 
   static size_t GetInfoEntrySize(size_t max_frames) {
@@ -126,6 +143,8 @@
 
   bool zygote_child;
 
+  std::string record_filename;
+
   static MallocDispatch dispatch;
 };
 
@@ -2148,7 +2167,7 @@
 }
 #endif
 
-void VerifyRecordAllocs() {
+void VerifyRecordAllocs(const std::string& record_filename) {
   std::string expected;
 
   void* pointer = debug_malloc(10);
@@ -2217,8 +2236,7 @@
 
   // Read all of the contents.
   std::string actual;
-  ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
-  ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
+  ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
 
   ASSERT_STREQ(expected.c_str(), actual.c_str());
 
@@ -2229,19 +2247,19 @@
 }
 
 TEST_F(MallocDebugTest, record_allocs_no_header) {
-  Init("record_allocs");
+  InitRecordAllocs("record_allocs");
 
-  VerifyRecordAllocs();
+  VerifyRecordAllocs(record_filename);
 }
 
 TEST_F(MallocDebugTest, record_allocs_with_header) {
-  Init("record_allocs front_guard");
+  InitRecordAllocs("record_allocs front_guard");
 
-  VerifyRecordAllocs();
+  VerifyRecordAllocs(record_filename);
 }
 
 TEST_F(MallocDebugTest, record_allocs_max) {
-  Init("record_allocs=5");
+  InitRecordAllocs("record_allocs=5");
 
   std::string expected;
 
@@ -2272,8 +2290,7 @@
 
   // Read all of the contents.
   std::string actual;
-  ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
-  ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
+  ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
 
   ASSERT_STREQ(expected.c_str(), actual.c_str());
 
@@ -2284,7 +2301,7 @@
 }
 
 TEST_F(MallocDebugTest, record_allocs_thread_done) {
-  Init("record_allocs=5");
+  InitRecordAllocs("record_allocs=5");
 
   static pid_t tid = 0;
   static void* pointer = nullptr;
@@ -2311,8 +2328,7 @@
 
   // Read all of the contents.
   std::string actual;
-  ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
-  ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
+  ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
 
   ASSERT_STREQ(expected.c_str(), actual.c_str());
 
@@ -2323,13 +2339,13 @@
 }
 
 TEST_F(MallocDebugTest, record_allocs_file_name_fail) {
-  Init("record_allocs=5");
+  InitRecordAllocs("record_allocs=5");
 
   // Delete the special.txt file and create a symbolic link there to
   // make sure the create file will fail.
-  unlink(RECORD_ALLOCS_FILE);
+  unlink(record_filename.c_str());
 
-  ASSERT_EQ(0, symlink("/data/local/tmp/does_not_exist", RECORD_ALLOCS_FILE));
+  ASSERT_EQ(0, symlink("/data/local/tmp/does_not_exist", record_filename.c_str()));
 
   std::string expected;
 
@@ -2350,10 +2366,10 @@
 
   // Read all of the contents.
   std::string actual;
-  ASSERT_FALSE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
+  ASSERT_FALSE(android::base::ReadFileToString(record_filename, &actual));
 
   // Unlink the file so the next dump passes.
-  ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
+  ASSERT_EQ(0, unlink(record_filename.c_str()));
 
   // Dump all of the data accumulated so far.
   ASSERT_TRUE(kill(getpid(), SIGRTMAX - 18) == 0);
@@ -2363,14 +2379,13 @@
   debug_free(pointer);
   expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
 
-  ASSERT_TRUE(android::base::ReadFileToString(RECORD_ALLOCS_FILE, &actual));
-  ASSERT_EQ(0, unlink(RECORD_ALLOCS_FILE));
+  ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
   ASSERT_STREQ(expected.c_str(), actual.c_str());
 
   ASSERT_STREQ("", getFakeLogBuf().c_str());
   std::string expected_log = android::base::StringPrintf(
       "6 malloc_debug Cannot create record alloc file %s: Too many symbolic links encountered\n",
-      RECORD_ALLOCS_FILE);
+      record_filename.c_str());
   ASSERT_STREQ(expected_log.c_str(), getFakeLogPrint().c_str());
 }