Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce92b0d0 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

More work on issue #17656716: Unhandled exception in Window Manager

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
parent 38646c19
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
+14 −4
Original line number Diff line number Diff line
@@ -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);
            }
            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);
            }
            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;
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -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
+6 −11
Original line number Diff line number Diff line
@@ -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);
        }