Loading libs/binder/RpcSession.cpp +8 −1 Original line number Diff line number Diff line Loading @@ -429,8 +429,9 @@ void RpcSession::join(sp<RpcSession>&& session, PreJoinSetupResult&& setupResult } } } else { ALOGE("Connection failed to init, closing with status %s", ALOGE("Connection failed to init, closing with status %s. Terminating!", statusToString(setupResult.status).c_str()); (void)session->shutdownAndWait(false); } sp<RpcSession::EventListener> listener; Loading @@ -450,6 +451,12 @@ void RpcSession::join(sp<RpcSession>&& session, PreJoinSetupResult&& setupResult "bad state: connection object guaranteed to be in list"); } // If you are hitting this, it's likely because whatever caused the thread to exit // in getAndExecuteCommand did not terminate the thread. We abort here, to make // this discoverable instead of potentially causing a deadlock. LOG_ALWAYS_FATAL_IF(!session->mShutdownTrigger->isTriggered(), "If a thread exits, we only support shutting down the entire RpcSession."); session = nullptr; if (listener != nullptr) { Loading libs/binder/RpcState.cpp +27 −14 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "Constants.h" #include "Debug.h" #include "FdTrigger.h" #include "RpcWireFormat.h" #include "Utils.h" Loading Loading @@ -866,26 +867,38 @@ status_t RpcState::processCommand( }); #endif // BINDER_WITH_KERNEL_IPC status_t result = NO_INIT; switch (command.command) { case RPC_COMMAND_TRANSACT: if (type != CommandType::ANY) return BAD_TYPE; return processTransact(connection, session, command, std::move(ancillaryFds)); result = processTransact(connection, session, command, std::move(ancillaryFds)); break; case RPC_COMMAND_DEC_STRONG: return processDecStrong(connection, session, command); } result = processDecStrong(connection, session, command); break; default: // We should always know the version of the opposing side, and since the // RPC-binder-level wire protocol is not self synchronizing, we have no way // to understand where the current command ends and the next one begins. We // also can't consider it a fatal error because this would allow any client // to kill us, so ending the session for misbehaving client. ALOGE("Unknown RPC command %d - terminating session. Header: %s. CommandType: %d. numFds: %zu", command.command, HexString(&command, sizeof(command)).c_str(), static_cast<int>(type), ancillaryFds.size()); ALOGE("Unknown RPC command %d - terminating session. Header: %s. CommandType: %d. " "numFds: %zu", command.command, HexString(&command, sizeof(command)).c_str(), static_cast<int>(type), ancillaryFds.size()); (void)session->shutdownAndWait(false); return DEAD_OBJECT; } if (result != OK) { LOG_ALWAYS_FATAL_IF(!session->mShutdownTrigger->isTriggered(), "Error during processing command must trigger shutdown! %s", statusToString(result).c_str()); } return result; } // THIS FUNCTION MUST SHUTDOWN IF IT ERRORS, ACCORDING TO processCommand. // THIS FUNCTION MUST ALWAYS READ THE FULL COMMAND, ACCORDING TO processCommand. status_t RpcState::processTransact( Loading Loading
libs/binder/RpcSession.cpp +8 −1 Original line number Diff line number Diff line Loading @@ -429,8 +429,9 @@ void RpcSession::join(sp<RpcSession>&& session, PreJoinSetupResult&& setupResult } } } else { ALOGE("Connection failed to init, closing with status %s", ALOGE("Connection failed to init, closing with status %s. Terminating!", statusToString(setupResult.status).c_str()); (void)session->shutdownAndWait(false); } sp<RpcSession::EventListener> listener; Loading @@ -450,6 +451,12 @@ void RpcSession::join(sp<RpcSession>&& session, PreJoinSetupResult&& setupResult "bad state: connection object guaranteed to be in list"); } // If you are hitting this, it's likely because whatever caused the thread to exit // in getAndExecuteCommand did not terminate the thread. We abort here, to make // this discoverable instead of potentially causing a deadlock. LOG_ALWAYS_FATAL_IF(!session->mShutdownTrigger->isTriggered(), "If a thread exits, we only support shutting down the entire RpcSession."); session = nullptr; if (listener != nullptr) { Loading
libs/binder/RpcState.cpp +27 −14 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "Constants.h" #include "Debug.h" #include "FdTrigger.h" #include "RpcWireFormat.h" #include "Utils.h" Loading Loading @@ -866,26 +867,38 @@ status_t RpcState::processCommand( }); #endif // BINDER_WITH_KERNEL_IPC status_t result = NO_INIT; switch (command.command) { case RPC_COMMAND_TRANSACT: if (type != CommandType::ANY) return BAD_TYPE; return processTransact(connection, session, command, std::move(ancillaryFds)); result = processTransact(connection, session, command, std::move(ancillaryFds)); break; case RPC_COMMAND_DEC_STRONG: return processDecStrong(connection, session, command); } result = processDecStrong(connection, session, command); break; default: // We should always know the version of the opposing side, and since the // RPC-binder-level wire protocol is not self synchronizing, we have no way // to understand where the current command ends and the next one begins. We // also can't consider it a fatal error because this would allow any client // to kill us, so ending the session for misbehaving client. ALOGE("Unknown RPC command %d - terminating session. Header: %s. CommandType: %d. numFds: %zu", command.command, HexString(&command, sizeof(command)).c_str(), static_cast<int>(type), ancillaryFds.size()); ALOGE("Unknown RPC command %d - terminating session. Header: %s. CommandType: %d. " "numFds: %zu", command.command, HexString(&command, sizeof(command)).c_str(), static_cast<int>(type), ancillaryFds.size()); (void)session->shutdownAndWait(false); return DEAD_OBJECT; } if (result != OK) { LOG_ALWAYS_FATAL_IF(!session->mShutdownTrigger->isTriggered(), "Error during processing command must trigger shutdown! %s", statusToString(result).c_str()); } return result; } // THIS FUNCTION MUST SHUTDOWN IF IT ERRORS, ACCORDING TO processCommand. // THIS FUNCTION MUST ALWAYS READ THE FULL COMMAND, ACCORDING TO processCommand. status_t RpcState::processTransact( Loading