Skip to content

Commit ce92b0d

Browse files
author
Dianne Hackborn
committed
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
1 parent 38646c1 commit ce92b0d

4 files changed

Lines changed: 28 additions & 18 deletions

File tree

core/java/android/app/ApplicationErrorReport.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ public void writeToParcel(Parcel dest, int flags) {
388388
dest.writeInt(throwLineNumber);
389389
dest.writeString(stackTrace);
390390
int total = dest.dataPosition()-start;
391-
if (total > 100*1024) {
391+
if (total > 10*1024) {
392392
Slog.d("Error", "ERR: exClass=" + exceptionClassName);
393393
Slog.d("Error", "ERR: exMsg=" + exceptionMessage);
394394
Slog.d("Error", "ERR: file=" + throwFileName);

core/java/android/os/Binder.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -430,16 +430,18 @@ private boolean execTransact(int code, long dataObj, long replyObj,
430430
} catch (RemoteException e) {
431431
if ((flags & FLAG_ONEWAY) != 0) {
432432
Log.w(TAG, "Binder call failed.", e);
433+
} else {
434+
reply.setDataPosition(0);
435+
reply.writeException(e);
433436
}
434-
reply.setDataPosition(0);
435-
reply.writeException(e);
436437
res = true;
437438
} catch (RuntimeException e) {
438439
if ((flags & FLAG_ONEWAY) != 0) {
439440
Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
441+
} else {
442+
reply.setDataPosition(0);
443+
reply.writeException(e);
440444
}
441-
reply.setDataPosition(0);
442-
reply.writeException(e);
443445
res = true;
444446
} catch (OutOfMemoryError e) {
445447
// Unconditionally log this, since this is generally unrecoverable.
@@ -452,6 +454,14 @@ private boolean execTransact(int code, long dataObj, long replyObj,
452454
checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
453455
reply.recycle();
454456
data.recycle();
457+
458+
// Just in case -- we are done with the IPC, so there should be no more strict
459+
// mode violations that have gathered for this thread. Either they have been
460+
// parceled and are now in transport off to the caller, or we are returning back
461+
// to the main transaction loop to wait for another incoming transaction. Either
462+
// way, strict mode begone!
463+
StrictMode.clearGatheredViolations();
464+
455465
return res;
456466
}
457467
}

core/java/android/os/StrictMode.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,7 +1693,7 @@ public static void onVmPolicyViolation(String message, Throwable originStack) {
16931693
int start = p.dataPosition();
16941694
violations.get(i).writeToParcel(p, 0 /* unused flags? */);
16951695
int size = p.dataPosition()-start;
1696-
if (size > 100*1024) {
1696+
if (size > 10*1024) {
16971697
Slog.d(TAG, "Wrote violation #" + i + " of " + violations.size() + ": "
16981698
+ (p.dataPosition()-start) + " bytes");
16991699
}
@@ -1725,6 +1725,11 @@ private static class LogStackTrace extends Exception {}
17251725
for (int i = 0; i < numViolations; ++i) {
17261726
if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i);
17271727
ViolationInfo info = new ViolationInfo(p, !currentlyGathering);
1728+
if (info.crashInfo.stackTrace.length() > 5000) {
1729+
RuntimeException here = new RuntimeException("here");
1730+
here.fillInStackTrace();
1731+
Slog.w(TAG, "Stack is getting large: " + info.crashInfo.stackTrace, here);
1732+
}
17281733
info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack;
17291734
BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
17301735
if (policy instanceof AndroidBlockGuardPolicy) {
@@ -2194,7 +2199,7 @@ public void writeToParcel(Parcel dest, int flags) {
21942199
dest.writeString(broadcastIntentAction);
21952200
dest.writeStringArray(tags);
21962201
int total = dest.dataPosition()-start;
2197-
if (total > 100*1024) {
2202+
if (total > 10*1024) {
21982203
Slog.d(TAG, "VIO: policy=" + policy + " dur=" + durationMillis
21992204
+ " numLoop=" + violationNumThisLoop
22002205
+ " anim=" + numAnimationsRunning

core/jni/android_util_Binder.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,7 @@ class JavaBBinder : public BBinder
264264
ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
265265

266266
IPCThreadState* thread_state = IPCThreadState::self();
267-
const int strict_policy_before = thread_state->getStrictModePolicy();
268-
thread_state->setLastTransactionBinderFlags(flags);
267+
const int32_t strict_policy_before = thread_state->getStrictModePolicy();
269268

270269
//printf("Transact from %p to Java code sending: ", this);
271270
//data.print();
@@ -284,15 +283,11 @@ class JavaBBinder : public BBinder
284283
env->DeleteLocalRef(excep);
285284
}
286285

287-
// Restore the Java binder thread's state if it changed while
288-
// processing a call (as it would if the Parcel's header had a
289-
// new policy mask and Parcel.enforceInterface() changed
290-
// it...)
291-
const int strict_policy_after = thread_state->getStrictModePolicy();
292-
if (strict_policy_after != strict_policy_before) {
293-
// Our thread-local...
294-
thread_state->setStrictModePolicy(strict_policy_before);
295-
// And the Java-level thread-local...
286+
// Check if the strict mode state changed while processing the
287+
// call. The Binder state will be restored by the underlying
288+
// Binder system in IPCThreadState, however we need to take care
289+
// of the parallel Java state as well.
290+
if (thread_state->getStrictModePolicy() != strict_policy_before) {
296291
set_dalvik_blockguard_policy(env, strict_policy_before);
297292
}
298293

0 commit comments

Comments
 (0)