Snap for 8730993 from fb02a510cffc20113785205a3130ca77b59ba08a to mainline-tzdata3-release

Change-Id: I89ed58150620bea80960b8591a4e8f01e618308a
diff --git a/Android.bp b/Android.bp
index 68457e5..77f126a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -48,9 +48,6 @@
         "libc_malloc_debug_backtrace",
         "libprocinfo",
     ],
-    header_libs: [
-        "libgtest_prod_headers",
-    ],
     export_include_dirs: ["include"],
     local_include_dirs: ["include"],
     version_script: "libmemunreachable.map",
@@ -64,9 +61,7 @@
         "tests/MemUnreachable_test.cpp",
     ],
     shared_libs: ["libmemunreachable"],
-    header_libs: [
-        "libbase_headers",
-    ],
+
     test_suites: ["device-tests"],
 }
 
@@ -76,7 +71,6 @@
     host_supported: true,
     srcs: [
         "tests/Allocator_test.cpp",
-        "tests/AtomicState_test.cpp",
         "tests/HeapWalker_test.cpp",
         "tests/LeakFolding_test.cpp",
     ],
@@ -105,9 +99,7 @@
             enabled: false,
         },
     },
-    header_libs: [
-        "libbase_headers",
-    ],
+
     test_suites: ["device-tests"],
 }
 
diff --git a/AtomicState.h b/AtomicState.h
deleted file mode 100644
index 365eab9..0000000
--- a/AtomicState.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <chrono>
-#include <functional>
-#include <mutex>
-#include <unordered_set>
-
-#include <gtest/gtest_prod.h>
-
-#include "android-base/macros.h"
-
-namespace android {
-
-/*
- * AtomicState manages updating or waiting on a state enum between multiple threads.
- */
-template <typename T>
-class AtomicState {
- public:
-  explicit AtomicState(T state) : state_(state) {}
-  ~AtomicState() = default;
-
-  /*
-   * Set the state to `to`.  Wakes up any waiters that are waiting on the new state.
-   */
-  void set(T to) {
-    std::lock_guard<std::mutex> lock(m_);
-    state_ = to;
-    cv_.notify_all();
-  }
-
-  /*
-   * If the state is `from`, change it to `to` and return true.  Otherwise don't change
-   * it and return false.  If the state is changed, wakes up any waiters that are waiting
-   * on the new state.
-   */
-  bool transition(T from, T to) {
-    return transition_or(from, to, [&] { return state_; });
-  }
-
-  /*
-   * If the state is `from`, change it to `to` and return true.  Otherwise, call `or_func`,
-   * set the state to the value it returns and return false.  Wakes up any waiters that are
-   * waiting on the new state.
-   */
-  bool transition_or(T from, T to, const std::function<T()>& orFunc) {
-    std::lock_guard<std::mutex> lock(m_);
-
-    bool failed = false;
-    if (state_ == from) {
-      state_ = to;
-    } else {
-      failed = true;
-      state_ = orFunc();
-    }
-    cv_.notify_all();
-
-    return !failed;
-  }
-
-  /*
-   * Block until the state is either `state1` or `state2`, or the time limit is reached.
-   * Returns true if the time limit was not reached, false if it was reached.
-   */
-  bool wait_for_either_of(T state1, T state2, std::chrono::milliseconds ms) {
-    std::unique_lock<std::mutex> lock(m_);
-    bool success = cv_.wait_for(lock, ms, [&] { return state_ == state1 || state_ == state2; });
-    return success;
-  }
-
- private:
-  T state_;
-  std::mutex m_;
-  std::condition_variable cv_;
-
-  FRIEND_TEST(AtomicStateTest, transition);
-  FRIEND_TEST(AtomicStateTest, wait);
-
-  DISALLOW_COPY_AND_ASSIGN(AtomicState);
-};
-
-}  // namespace android
diff --git a/MemUnreachable.cpp b/MemUnreachable.cpp
index d37819a..b02a77e 100644
--- a/MemUnreachable.cpp
+++ b/MemUnreachable.cpp
@@ -29,7 +29,6 @@
 #include <backtrace.h>
 
 #include "Allocator.h"
-#include "AtomicState.h"
 #include "Binder.h"
 #include "HeapWalker.h"
 #include "Leak.h"
@@ -38,6 +37,7 @@
 #include "ProcessMappings.h"
 #include "PtracerThread.h"
 #include "ScopedDisableMalloc.h"
+#include "Semaphore.h"
 #include "ThreadCapture.h"
 
 #include "bionic.h"
@@ -282,13 +282,6 @@
   return (val == 1) ? "" : "s";
 }
 
-enum State {
-  STARTING = 0,
-  PAUSING,
-  COLLECTING,
-  ABORT,
-};
-
 bool GetUnreachableMemory(UnreachableMemoryInfo& info, size_t limit) {
   if (info.version > 0) {
     MEM_ALOGE("unsupported UnreachableMemoryInfo.version %zu in GetUnreachableMemory",
@@ -301,7 +294,7 @@
 
   Heap heap;
 
-  AtomicState<State> state(STARTING);
+  Semaphore continue_parent_sem;
   LeakPipe pipe;
 
   PtracerThread thread{[&]() -> int {
@@ -310,13 +303,6 @@
     /////////////////////////////////////////////
     MEM_ALOGI("collecting thread info for process %d...", parent_pid);
 
-    if (!state.transition_or(STARTING, PAUSING, [&] {
-          MEM_ALOGI("collecting thread expected state STARTING, aborting");
-          return ABORT;
-        })) {
-      return 1;
-    }
-
     ThreadCapture thread_capture(parent_pid, heap);
     allocator::vector<ThreadInfo> thread_info(heap);
     allocator::vector<Mapping> mappings(heap);
@@ -324,34 +310,24 @@
 
     // ptrace all the threads
     if (!thread_capture.CaptureThreads()) {
-      state.set(ABORT);
+      continue_parent_sem.Post();
       return 1;
     }
 
     // collect register contents and stacks
     if (!thread_capture.CapturedThreadInfo(thread_info)) {
-      state.set(ABORT);
+      continue_parent_sem.Post();
       return 1;
     }
 
     // snapshot /proc/pid/maps
     if (!ProcessMappings(parent_pid, mappings)) {
-      state.set(ABORT);
+      continue_parent_sem.Post();
       return 1;
     }
 
     if (!BinderReferences(refs)) {
-      state.set(ABORT);
-      return 1;
-    }
-
-    // Atomically update the state from PAUSING to COLLECTING.
-    // The main thread may have given up waiting for this thread to finish
-    // pausing, in which case it will have changed the state to ABORT.
-    if (!state.transition_or(PAUSING, COLLECTING, [&] {
-          MEM_ALOGI("collecting thread aborting");
-          return ABORT;
-        })) {
+      continue_parent_sem.Post();
       return 1;
     }
 
@@ -361,6 +337,7 @@
     // can drop the malloc locks, it will block until the collection thread
     // exits.
     thread_capture.ReleaseThread(parent_tid);
+    continue_parent_sem.Post();
 
     // fork a process to do the heap walking
     int ret = fork();
@@ -423,15 +400,7 @@
 
     // Wait for the collection thread to signal that it is ready to fork the
     // heap walker process.
-    if (!state.wait_for_either_of(COLLECTING, ABORT, 30s)) {
-      // The pausing didn't finish within 30 seconds, attempt to atomically
-      // update the state from PAUSING to ABORT.  The collecting thread
-      // may have raced with the timeout and already updated the state to
-      // COLLECTING, in which case aborting is not necessary.
-      if (state.transition(PAUSING, ABORT)) {
-        MEM_ALOGI("main thread timed out waiting for collecting thread");
-      }
-    }
+    continue_parent_sem.Wait(30s);
 
     // Re-enable malloc so the collection thread can fork.
   }
diff --git a/OWNERS b/OWNERS
index e672416..9127a93 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,2 @@
-# Bug component: 391836
 ccross@google.com
 cferris@google.com
diff --git a/Semaphore.h b/Semaphore.h
new file mode 100644
index 0000000..cd73972
--- /dev/null
+++ b/Semaphore.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIBMEMUNREACHABLE_SEMAPHORE_H_
+#define LIBMEMUNREACHABLE_SEMAPHORE_H_
+
+#include <chrono>
+#include <mutex>
+
+#include "android-base/macros.h"
+
+namespace android {
+
+class Semaphore {
+ public:
+  explicit Semaphore(int count = 0) : count_(count) {}
+  ~Semaphore() = default;
+
+  void Wait(std::chrono::milliseconds ms) {
+    std::unique_lock<std::mutex> lk(m_);
+    cv_.wait_for(lk, ms, [&] {
+      if (count_ > 0) {
+        count_--;
+        return true;
+      }
+      return false;
+    });
+  }
+  void Post() {
+    {
+      std::lock_guard<std::mutex> lk(m_);
+      count_++;
+    }
+    cv_.notify_one();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Semaphore);
+
+  int count_;
+  std::mutex m_;
+  std::condition_variable cv_;
+};
+
+}  // namespace android
+
+#endif  // LIBMEMUNREACHABLE_SEMAPHORE_H_
diff --git a/TEST_MAPPING b/TEST_MAPPING
deleted file mode 100644
index 3ec91f8..0000000
--- a/TEST_MAPPING
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "memunreachable_test"
-    },
-    {
-      "name": "memunreachable_unit_test"
-    },
-    {
-      "name": "memunreachable_binder_test"
-    }
-  ]
-}
diff --git a/bionic.h b/bionic.h
index 49bf255..dd1ec79 100644
--- a/bionic.h
+++ b/bionic.h
@@ -20,7 +20,6 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <sys/cdefs.h>
-#include <sys/types.h>
 
 __BEGIN_DECLS
 
diff --git a/tests/AtomicState_test.cpp b/tests/AtomicState_test.cpp
deleted file mode 100644
index 7fb2806..0000000
--- a/tests/AtomicState_test.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <AtomicState.h>
-
-#include <chrono>
-#include <thread>
-
-#include <gtest/gtest.h>
-
-using namespace std::chrono_literals;
-
-namespace android {
-
-enum AtomicStateTestEnum {
-  A,
-  B,
-  C,
-  D,
-  E,
-};
-
-class AtomicStateTest : public testing::Test {
- protected:
-  AtomicStateTest() : state_(A) {}
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-
-  AtomicState<AtomicStateTestEnum> state_;
-};
-
-TEST_F(AtomicStateTest, transition) {
-  ASSERT_EQ(A, state_.state_);
-
-  // Starts as A, transition from B fails
-  ASSERT_FALSE(state_.transition(B, C));
-  ASSERT_EQ(A, state_.state_);
-
-  // transition from A to B
-  ASSERT_TRUE(state_.transition(A, B));
-  ASSERT_EQ(B, state_.state_);
-
-  // State is B, transition from A fails
-  ASSERT_FALSE(state_.transition(A, B));
-  ASSERT_EQ(B, state_.state_);
-
-  // State is B, transition_or from A calls the lambda
-  bool lambda = false;
-  bool already_locked = false;
-  state_.transition_or(A, B, [&] {
-    // The lock should be held in the lambda
-    if (state_.m_.try_lock()) {
-      state_.m_.unlock();
-    } else {
-      already_locked = true;
-    }
-    lambda = true;
-    return B;
-  });
-  ASSERT_TRUE(lambda);
-  ASSERT_TRUE(already_locked);
-  ASSERT_EQ(B, state_.state_);
-
-  // State is C, transition_or from B to C does not call the lambda
-  lambda = false;
-  state_.transition_or(B, C, [&] {
-    lambda = true;
-    return C;
-  });
-  ASSERT_FALSE(lambda);
-  ASSERT_EQ(C, state_.state_);
-}
-
-TEST_F(AtomicStateTest, wait) {
-  ASSERT_EQ(A, state_.state_);
-
-  // Starts as A, wait_for_either_of B, C returns false
-  ASSERT_FALSE(state_.wait_for_either_of(B, C, 10ms));
-
-  // Starts as A, wait_for_either_of A, B returns true
-  ASSERT_TRUE(state_.wait_for_either_of(A, B, 1s));
-
-  {
-    std::thread t([&] {
-      usleep(10000);
-      state_.set(B);
-    });
-
-    // Wait ing for B or C returns true after state is set to B
-    ASSERT_TRUE(state_.wait_for_either_of(B, C, 1s));
-
-    t.join();
-  }
-
-  ASSERT_EQ(B, state_.state_);
-  {
-    std::thread t([&] {
-      usleep(10000);
-      state_.transition(B, C);
-    });
-
-    // Waiting for A or C returns true after state is transitioned to C
-    ASSERT_TRUE(state_.wait_for_either_of(A, C, 1s));
-
-    t.join();
-  }
-
-  ASSERT_EQ(C, state_.state_);
-  {
-    std::thread t([&] {
-      usleep(10000);
-      state_.transition(C, D);
-    });
-
-    // Waiting for A or B returns false after state is transitioned to D
-    ASSERT_FALSE(state_.wait_for_either_of(A, B, 100ms));
-
-    t.join();
-  }
-}
-
-}  // namespace android
diff --git a/tests/DisableMalloc_test.cpp b/tests/DisableMalloc_test.cpp
index ae560ed..f446719 100644
--- a/tests/DisableMalloc_test.cpp
+++ b/tests/DisableMalloc_test.cpp
@@ -19,8 +19,6 @@
 #include <chrono>
 #include <functional>
 
-#include <android-base/test_utils.h>
-
 #include <ScopedDisableMalloc.h>
 #include <gtest/gtest.h>
 
@@ -37,11 +35,6 @@
     t.it_value.tv_usec = (us - s).count();
     setitimer(ITIMER_REAL, &t, NULL);
   }
-
-  void SetUp() override {
-    // HWASan does not support malloc_disable.
-    SKIP_WITH_HWASAN;
-  }
 };
 
 TEST_F(DisableMallocTest, reenable) {
diff --git a/tests/HeapWalker_test.cpp b/tests/HeapWalker_test.cpp
index f78fd66..9610cd6 100644
--- a/tests/HeapWalker_test.cpp
+++ b/tests/HeapWalker_test.cpp
@@ -25,14 +25,6 @@
 
 namespace android {
 
-static inline uintptr_t UntagAddress(uintptr_t addr) {
-#if defined(__aarch64__)
-  constexpr uintptr_t mask = (static_cast<uintptr_t>(1) << 56) - 1;
-  addr = addr & mask;
-#endif
-  return addr;
-}
-
 class HeapWalkerTest : public ::testing::Test {
  public:
   HeapWalkerTest() : disable_malloc_(), heap_() {}
@@ -121,8 +113,8 @@
   EXPECT_EQ(1U, num_leaks);
   EXPECT_EQ(16U, leaked_bytes);
   ASSERT_EQ(1U, leaked.size());
-  EXPECT_EQ(UntagAddress(buffer_begin(buffer2)), leaked[0].begin);
-  EXPECT_EQ(UntagAddress(buffer_end(buffer2)), leaked[0].end);
+  EXPECT_EQ(buffer_begin(buffer2), leaked[0].begin);
+  EXPECT_EQ(buffer_end(buffer2), leaked[0].end);
 }
 
 TEST_F(HeapWalkerTest, live) {
diff --git a/tests/MemUnreachable_test.cpp b/tests/MemUnreachable_test.cpp
index 8bc176b..9cb1623 100644
--- a/tests/MemUnreachable_test.cpp
+++ b/tests/MemUnreachable_test.cpp
@@ -19,8 +19,6 @@
 #include <sys/prctl.h>
 #include <unistd.h>
 
-#include <android-base/test_utils.h>
-
 #include <gtest/gtest.h>
 
 #include <memunreachable/memunreachable.h>
@@ -56,8 +54,6 @@
 class MemunreachableTest : public ::testing::Test {
  protected:
   virtual void SetUp() {
-    // HWASan does not support malloc_disable, which is required by memunreachable.
-    SKIP_WITH_HWASAN;
     CleanStack(8192);
     CleanTcache();
   }
@@ -248,7 +244,9 @@
 
 TEST_F(MemunreachableTest, notdumpable) {
   if (getuid() == 0) {
-    GTEST_SKIP() << "Not testable when running as root";
+    // TODO(ccross): make this a skipped test when gtest supports them
+    printf("[ SKIP     ] Not testable when running as root\n");
+    return;
   }
 
   ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 0));