OSDN Git Service

ART: Reprint long messages on abort
authorAndreas Gampe <agampe@google.com>
Tue, 4 Oct 2016 02:47:08 +0000 (19:47 -0700)
committerAndreas Gampe <agampe@google.com>
Tue, 4 Oct 2016 02:47:08 +0000 (19:47 -0700)
Add an abort message parameter to Runtime::Abort. In case the message
is multiline (and will thus not be completely preserved in the
Android abort reason), reprint the message after all threads have
been dumped.

Bug: 31893081
Test: m test-art-host
Change-Id: I65bc77691fec79f7c868a90d6132805fcc91e473

runtime/base/logging.cc
runtime/indirect_reference_table.cc
runtime/runtime.cc
runtime/runtime.h

index 17873b5..c305c4a 100644 (file)
@@ -64,7 +64,7 @@ static void RuntimeAborter(const char* abort_message) {
 #else
   UNUSED(abort_message);
 #endif
-  Runtime::Abort();
+  Runtime::Abort(abort_message);
 }
 
 void InitLogging(char* argv[]) {
index 1eee7c4..b742ccc 100644 (file)
@@ -129,15 +129,9 @@ IndirectRef IndirectReferenceTable::Add(uint32_t cookie, mirror::Object* obj) {
   DCHECK_GE(segment_state_.parts.numHoles, prevState.parts.numHoles);
 
   if (topIndex == max_entries_) {
-    std::ostringstream oss;
-    oss << "JNI ERROR (app bug): " << kind_ << " table overflow "
-        << "(max=" << max_entries_ << ")\n"
-        << MutatorLockedDumpable<IndirectReferenceTable>(*this);
-    if (VLOG_IS_ON(jni)) {
-      LOG(FATAL) << oss.str();
-    } else {
-      LOG_FATAL_THIS_THREAD_ONLY(oss.str());
-    }
+    LOG(FATAL) << "JNI ERROR (app bug): " << kind_ << " table overflow "
+               << "(max=" << max_entries_ << ")\n"
+               << MutatorLockedDumpable<IndirectReferenceTable>(*this);
   }
 
   // We know there's enough room in the table.  Now we just need to find
index df0dca0..f6a854c 100644 (file)
@@ -422,7 +422,7 @@ struct AbortState {
   }
 };
 
-void Runtime::Abort() {
+void Runtime::Abort(const char* msg) {
   gAborting++;  // set before taking any locks
 
   // Ensure that we don't have multiple threads trying to abort at once,
@@ -437,6 +437,12 @@ void Runtime::Abort() {
   AbortState state;
   LOG(FATAL_WITHOUT_ABORT) << Dumpable<AbortState>(state);
 
+  // Sometimes we dump long messages, and the Android abort message only retains the first line.
+  // In those cases, just log the message again, to avoid logcat limits.
+  if (msg != nullptr && strchr(msg, '\n') != nullptr) {
+    LOG(FATAL_WITHOUT_ABORT) << msg;
+  }
+
   // Call the abort hook if we have one.
   if (Runtime::Current() != nullptr && Runtime::Current()->abort_ != nullptr) {
     LOG(FATAL_WITHOUT_ABORT) << "Calling abort hook...";
index 30f1b4a..84c6b6f 100644 (file)
@@ -225,7 +225,7 @@ class Runtime {
 
   // Aborts semi-cleanly. Used in the implementation of LOG(FATAL), which most
   // callers should prefer.
-  NO_RETURN static void Abort() REQUIRES(!Locks::abort_lock_);
+  NO_RETURN static void Abort(const char* msg) REQUIRES(!Locks::abort_lock_);
 
   // Returns the "main" ThreadGroup, used when attaching user threads.
   jobject GetMainThreadGroup() const;