Check using destroyed mutexes.

For apps built for Android < P, return EBUSY.
For apps built for Android >= P, abort.

This is to keep old apps work, and help debugging
apps built for >= P.

Bug: http://b/74632097
Test: run bionic-unit-tests.
Test: run bionic-benchmark.

Change-Id: I5271565a1a6ad12678f85d558a7f862a2b7aab4b
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 523ed63..e9eb507 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -1718,7 +1718,6 @@
 
   void destroy() {
     ASSERT_EQ(0, pthread_mutex_destroy(&lock));
-    ASSERT_EQ(EBUSY, pthread_mutex_destroy(&lock));
   }
 
   DISALLOW_COPY_AND_ASSIGN(PthreadMutex);
@@ -2053,6 +2052,27 @@
   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
 }
 
+TEST(pthread, pthread_mutex_using_destroyed_mutex) {
+#if defined(__BIONIC__)
+  pthread_mutex_t m;
+  ASSERT_EQ(0, pthread_mutex_init(&m, nullptr));
+  ASSERT_EQ(0, pthread_mutex_destroy(&m));
+  ASSERT_EXIT(pthread_mutex_lock(&m), ::testing::KilledBySignal(SIGABRT),
+              "pthread_mutex_lock called on a destroyed mutex");
+  ASSERT_EXIT(pthread_mutex_unlock(&m), ::testing::KilledBySignal(SIGABRT),
+              "pthread_mutex_unlock called on a destroyed mutex");
+  ASSERT_EXIT(pthread_mutex_trylock(&m), ::testing::KilledBySignal(SIGABRT),
+              "pthread_mutex_trylock called on a destroyed mutex");
+  timespec ts;
+  ASSERT_EXIT(pthread_mutex_timedlock(&m, &ts), ::testing::KilledBySignal(SIGABRT),
+              "pthread_mutex_timedlock called on a destroyed mutex");
+  ASSERT_EXIT(pthread_mutex_destroy(&m), ::testing::KilledBySignal(SIGABRT),
+              "pthread_mutex_destroy called on a destroyed mutex");
+#else
+  GTEST_LOG_(INFO) << "This test tests bionic pthread mutex implementation details.";
+#endif
+}
+
 class StrictAlignmentAllocator {
  public:
   void* allocate(size_t size, size_t alignment) {