summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2019-06-12 10:00:57 -0700
committer Treehugger Robot <treehugger-gerrit@google.com> 2019-06-14 17:58:19 +0000
commit3e2446bbe9326786a970c88bbfac80b8ed8e5cdd (patch)
tree3495f831cb926030c57901152a939718ff12886e
parent1adb04fd1ab7a44b5bf0e0d8deb522b68849a2f6 (diff)
ART: Correctly handle an abort from an unattached thread
Libbase may be shared with other platform components. In that case, if the aborting thread is attached to the runtime, ART will print its usual dump to be helpful. If the thread is unattached, this must not be done as it would violate mutex invariants. Bug: 135056249 Test: m test-art-host-gtest-runtime_test Change-Id: I61c3df5fdbc8ddaf279f39dc653738016986dcd9
-rw-r--r--runtime/base/mutex-inl.h4
-rw-r--r--runtime/runtime.cc9
-rw-r--r--runtime/runtime_test.cc23
3 files changed, 34 insertions, 2 deletions
diff --git a/runtime/base/mutex-inl.h b/runtime/base/mutex-inl.h
index 22b76d231b..821c75d9b3 100644
--- a/runtime/base/mutex-inl.h
+++ b/runtime/base/mutex-inl.h
@@ -82,7 +82,9 @@ static inline void CheckUnattachedThread(LockLevel level) NO_THREAD_SAFETY_ANALY
// Avoid recursive death.
level == kAbortLock ||
// Locks at the absolute top of the stack can be locked at any time.
- level == kTopLockLevel) << level;
+ level == kTopLockLevel ||
+ // The unexpected signal handler may be catching signals from any thread.
+ level == kUnexpectedSignalLock) << level;
}
}
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 93ba622b04..3ad0504405 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -610,6 +610,15 @@ void Runtime::Abort(const char* msg) {
#endif
}
+ // May be coming from an unattached thread.
+ if (Thread::Current() == nullptr) {
+ Runtime* current = Runtime::Current();
+ if (current != nullptr && current->IsStarted() && !current->IsShuttingDown(nullptr)) {
+ abort();
+ UNREACHABLE();
+ }
+ }
+
{
// Ensure that we don't have multiple threads trying to abort at once,
// which would result in significantly worse diagnostics.
diff --git a/runtime/runtime_test.cc b/runtime/runtime_test.cc
index 282e43071e..3fe281bd5f 100644
--- a/runtime/runtime_test.cc
+++ b/runtime/runtime_test.cc
@@ -14,10 +14,13 @@
* limitations under the License.
*/
+#include "common_runtime_test.h"
+
+#include <thread>
+
#include "android-base/logging.h"
#include "base/locks.h"
#include "base/mutex.h"
-#include "common_runtime_test.h"
#include "runtime.h"
#include "thread-current-inl.h"
@@ -54,4 +57,22 @@ TEST_F(RuntimeTest, AbortWithThreadSuspendCountLockHeld) {
}, kDeathRegex);
}
+TEST_F(RuntimeTest, AbortFromUnattachedThread) {
+ // This assumes the test is run single-threaded: do not start the runtime to avoid daemon threads.
+
+ constexpr const char* kDeathRegex = "Going down";
+ ASSERT_EXIT({
+ // The regex only works if we can ensure output goes to stderr.
+ android::base::SetLogger(android::base::StderrLogger);
+
+ Thread::Current()->TransitionFromSuspendedToRunnable();
+ runtime_->Start();
+
+ std::thread t([]() {
+ LOG(FATAL) << "Going down";
+ });
+ t.join();
+ }, ::testing::KilledBySignal(SIGABRT), kDeathRegex);
+}
+
} // namespace art