OSDN Git Service

ART: Do not abort on exception in CreatePeer
authorAndreas Gampe <agampe@google.com>
Thu, 1 Oct 2015 23:47:26 +0000 (16:47 -0700)
committerAndreas Gampe <agampe@google.com>
Thu, 8 Oct 2015 18:16:06 +0000 (11:16 -0700)
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

runtime/thread.cc

index 12b2e88..c317591 100644 (file)
@@ -730,6 +730,18 @@ Thread* Thread::Attach(const char* thread_name, bool as_daemon, jobject thread_g
   // 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 @@ void Thread::CreatePeer(const char* name, bool as_daemon, jobject thread_group)
                                 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 @@ void Thread::FinishStartup() {
   // Finish attaching the main thread.
   ScopedObjectAccess soa(Thread::Current());
   Thread::Current()->CreatePeer("main", false, runtime->GetMainThreadGroup());
+  Thread::Current()->AssertNoPendingException();
 
   Runtime::Current()->GetClassLinker()->RunRootClinits();
 }