From ae58f43927d1ea51582e0b82f3f2bf2bda83c144 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Thu, 5 Aug 2021 17:53:16 -0700 Subject: libbinder: RPC fix 'Die' race Before this change, what would normally happen is this: 1. we connect to a server and make some calls 2. we make the Die call which returns DEAD_OBJECT 3. we send decStrong on the root binder 4. decStrong on the root binder returns a failure 5. rpcSend calls shutdownAndWait, to terminate the session However, we actually know we should terminate the session at (2) (any failure here indicates a serious problem). This was causing a flake because sometimes (being a send only w/ no read), (4) would return a success. So, we wouldn't shutdown the session. Fixes: 200167417 Test: binderRpcTest --gtest_filter="*Die*" (on Pixel 3, repeatedly) Test: binderRpcTest (on Pixel 3, w/ and w/o this change several times - this does not introduce additional failures, and failures are tracked by b/200173589) Change-Id: I4894c2dd710b8cda59883c91e002b52ad67b1e26 --- libs/binder/RpcState.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'libs/binder/RpcState.cpp') diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp index 11a083ac11..dcba837a85 100644 --- a/libs/binder/RpcState.cpp +++ b/libs/binder/RpcState.cpp @@ -323,6 +323,7 @@ status_t RpcState::rpcRec(const sp& connection, status != OK) { LOG_RPC_DETAIL("Failed to read %s (%zu bytes) on RpcTransport %p, error: %s", what, size, connection->rpcTransport.get(), statusToString(status).c_str()); + (void)session->shutdownAndWait(false); return status; } @@ -531,8 +532,8 @@ status_t RpcState::waitForReply(const sp& connection, const sp& session, Parcel* reply) { RpcWireHeader command; while (true) { - if (status_t status = - rpcRec(connection, session, "command header", &command, sizeof(command)); + if (status_t status = rpcRec(connection, session, "command header (for reply)", &command, + sizeof(command)); status != OK) return status; @@ -601,7 +602,8 @@ status_t RpcState::getAndExecuteCommand(const sp& con LOG_RPC_DETAIL("getAndExecuteCommand on RpcTransport %p", connection->rpcTransport.get()); RpcWireHeader command; - if (status_t status = rpcRec(connection, session, "command header", &command, sizeof(command)); + if (status_t status = rpcRec(connection, session, "command header (for server)", &command, + sizeof(command)); status != OK) return status; -- cgit v1.2.3-59-g8ed1b