Binder: Log exceptions originating from the binder stub for oneway calls

- Under a normal situation, if an exception happens in managed, the stack trace
  will be printed to logcat.
- Hitherto, the Binder#execTransact call silently caught exceptions and passed
  them to the remote side with Parcel#writeException
- Although this behavior might be acceptable when there is a remote side,
  for FLAG_ONEWAY calls the exception effectively disappeared.
- From the user point of view, it looked like code execution "halted" when an
  exception was thrown.

This tries to make the binder exception handling behavior more like normal,
by printing the exception to the log, to give a better indication of what
happened.

Change-Id: I1f37f0468f61e766a71db60d2fda2104936ab096
This commit is contained in:
Igor Murashkin
2013-08-16 14:07:11 -07:00
parent 2743990343
commit 7eb6cfe10b

View File

@@ -399,17 +399,27 @@ public class Binder implements IBinder {
// but all that does is rewind it, and we just got these from an IPC,
// so we'll just call it directly.
boolean res;
// Log any exceptions as warnings, don't silently suppress them.
// If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
try {
res = onTransact(code, data, reply, flags);
} catch (RemoteException e) {
if ((flags & FLAG_ONEWAY) != 0) {
Log.w(TAG, "Binder call failed.", 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);
}
reply.setDataPosition(0);
reply.writeException(e);
res = true;
} catch (OutOfMemoryError e) {
// Unconditionally log this, since this is generally unrecoverable.
Log.e(TAG, "Caught an OutOfMemoryError from the binder stub implementation.", e);
RuntimeException re = new RuntimeException("Out of memory", e);
reply.setDataPosition(0);
reply.writeException(re);