ART: Do not abort on exception in CreatePeer
Different parts of CreatePeer may throw an exception, especially
the Thread constructor. Do not abort in such a case, but return
and report a failure to attach/create a thread.
Bug: 24200698
(cherry picked from commit 2a196784553f4fd0c0f7d4b8aac87281db3a4748)
Change-Id: I06f2c997f0451c71f791d1f12bea6f8ee65e8ab2
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 12b2e88..c317591 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -730,6 +730,18 @@
// a native peer!
if (create_peer) {
self->CreatePeer(thread_name, as_daemon, thread_group);
+ if (self->IsExceptionPending()) {
+ // We cannot keep the exception around, as we're deleting self. Try to be helpful and log it.
+ {
+ ScopedObjectAccess soa(self);
+ LOG(ERROR) << "Exception creating thread peer:";
+ LOG(ERROR) << self->GetException()->Dump();
+ self->ClearException();
+ }
+ runtime->GetThreadList()->Unregister(self);
+ // Unregister deletes self, no need to do this here.
+ return nullptr;
+ }
} else {
// These aren't necessary, but they improve diagnostics for unit tests & command-line tools.
if (thread_name != nullptr) {
@@ -788,7 +800,9 @@
WellKnownClasses::java_lang_Thread,
WellKnownClasses::java_lang_Thread_init,
thread_group, thread_name.get(), thread_priority, thread_is_daemon);
- AssertNoPendingException();
+ if (IsExceptionPending()) {
+ return;
+ }
Thread* self = this;
DCHECK_EQ(self, Thread::Current());
@@ -1536,6 +1550,7 @@
// Finish attaching the main thread.
ScopedObjectAccess soa(Thread::Current());
Thread::Current()->CreatePeer("main", false, runtime->GetMainThreadGroup());
+ Thread::Current()->AssertNoPendingException();
Runtime::Current()->GetClassLinker()->RunRootClinits();
}