OSDN Git Service

More work on issue #17656716: Unhandled exception in Window Manager
authorDianne Hackborn <hackbod@google.com>
Tue, 30 Sep 2014 18:28:18 +0000 (11:28 -0700)
committerDianne Hackborn <hackbod@google.com>
Tue, 30 Sep 2014 18:28:18 +0000 (11:28 -0700)
Drop down the limit on when we log, since under normal operation we
will never get more than a few K of data due to strict mode.

Try to clean up the code paths coming in and out of binder IPCs to
plug any places where we could disrupt the gather flag of a thread,
causing it to keep gathering stack crawls (which is the thing that
is causing our strict mode data to become so large).

Change-Id: I9a46512283d33e863c429840b465855d1fabb74e

core/java/android/app/ApplicationErrorReport.java
core/java/android/os/Binder.java
core/java/android/os/StrictMode.java
core/jni/android_util_Binder.cpp

index be4e80e..841bd16 100644 (file)
@@ -388,7 +388,7 @@ public class ApplicationErrorReport implements Parcelable {
             dest.writeInt(throwLineNumber);
             dest.writeString(stackTrace);
             int total = dest.dataPosition()-start;
-            if (total > 100*1024) {
+            if (total > 10*1024) {
                 Slog.d("Error", "ERR: exClass=" + exceptionClassName);
                 Slog.d("Error", "ERR: exMsg=" + exceptionMessage);
                 Slog.d("Error", "ERR: file=" + throwFileName);
index f5fc0d7..bbf6ed8 100644 (file)
@@ -430,16 +430,18 @@ public class Binder implements IBinder {
         } catch (RemoteException e) {
             if ((flags & FLAG_ONEWAY) != 0) {
                 Log.w(TAG, "Binder call failed.", e);
+            } else {
+                reply.setDataPosition(0);
+                reply.writeException(e);
             }
-            reply.setDataPosition(0);
-            reply.writeException(e);
             res = true;
         } catch (RuntimeException e) {
             if ((flags & FLAG_ONEWAY) != 0) {
                 Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
+            } else {
+                reply.setDataPosition(0);
+                reply.writeException(e);
             }
-            reply.setDataPosition(0);
-            reply.writeException(e);
             res = true;
         } catch (OutOfMemoryError e) {
             // Unconditionally log this, since this is generally unrecoverable.
@@ -452,6 +454,14 @@ public class Binder implements IBinder {
         checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
         reply.recycle();
         data.recycle();
+
+        // Just in case -- we are done with the IPC, so there should be no more strict
+        // mode violations that have gathered for this thread.  Either they have been
+        // parceled and are now in transport off to the caller, or we are returning back
+        // to the main transaction loop to wait for another incoming transaction.  Either
+        // way, strict mode begone!
+        StrictMode.clearGatheredViolations();
+
         return res;
     }
 }
index 4e9d1f0..0e561bd 100644 (file)
@@ -1693,7 +1693,7 @@ public final class StrictMode {
                 int start = p.dataPosition();
                 violations.get(i).writeToParcel(p, 0 /* unused flags? */);
                 int size = p.dataPosition()-start;
-                if (size > 100*1024) {
+                if (size > 10*1024) {
                     Slog.d(TAG, "Wrote violation #" + i + " of " + violations.size() + ": "
                             + (p.dataPosition()-start) + " bytes");
                 }
@@ -1725,6 +1725,11 @@ public final class StrictMode {
         for (int i = 0; i < numViolations; ++i) {
             if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call.  i=" + i);
             ViolationInfo info = new ViolationInfo(p, !currentlyGathering);
+            if (info.crashInfo.stackTrace.length() > 5000) {
+                RuntimeException here = new RuntimeException("here");
+                here.fillInStackTrace();
+                Slog.w(TAG, "Stack is getting large: " + info.crashInfo.stackTrace, here);
+            }
             info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack;
             BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
             if (policy instanceof AndroidBlockGuardPolicy) {
@@ -2194,7 +2199,7 @@ public final class StrictMode {
             dest.writeString(broadcastIntentAction);
             dest.writeStringArray(tags);
             int total = dest.dataPosition()-start;
-            if (total > 100*1024) {
+            if (total > 10*1024) {
                 Slog.d(TAG, "VIO: policy=" + policy + " dur=" + durationMillis
                         + " numLoop=" + violationNumThisLoop
                         + " anim=" + numAnimationsRunning
index 2dbd382..e400698 100644 (file)
@@ -264,8 +264,7 @@ protected:
         ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
 
         IPCThreadState* thread_state = IPCThreadState::self();
-        const int strict_policy_before = thread_state->getStrictModePolicy();
-        thread_state->setLastTransactionBinderFlags(flags);
+        const int32_t strict_policy_before = thread_state->getStrictModePolicy();
 
         //printf("Transact from %p to Java code sending: ", this);
         //data.print();
@@ -284,15 +283,11 @@ protected:
             env->DeleteLocalRef(excep);
         }
 
-        // Restore the Java binder thread's state if it changed while
-        // processing a call (as it would if the Parcel's header had a
-        // new policy mask and Parcel.enforceInterface() changed
-        // it...)
-        const int strict_policy_after = thread_state->getStrictModePolicy();
-        if (strict_policy_after != strict_policy_before) {
-            // Our thread-local...
-            thread_state->setStrictModePolicy(strict_policy_before);
-            // And the Java-level thread-local...
+        // Check if the strict mode state changed while processing the
+        // call.  The Binder state will be restored by the underlying
+        // Binder system in IPCThreadState, however we need to take care
+        // of the parallel Java state as well.
+        if (thread_state->getStrictModePolicy() != strict_policy_before) {
             set_dalvik_blockguard_policy(env, strict_policy_before);
         }