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

Commit ec2770e2 authored by Steven Moreland's avatar Steven Moreland
Browse files

RPC Binder: log when session fails w/ shutdown

When a session has an error, such that we can't
recover the current connection, we have to shutdown
the entire session, as we have no way to recover it
and don't want to continue with certain connections
not working.

Bug: 416772676
Test: binderRpcTest
Change-Id: I1326691a1d35d269ed653e0be6eeecaff72f2344
parent 8e8653af
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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) {
+27 −14
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#include "Constants.h"
#include "Debug.h"
#include "FdTrigger.h"
#include "RpcWireFormat.h"
#include "Utils.h"

@@ -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(