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

Commit 13a43c92 authored by Steven Moreland's avatar Steven Moreland
Browse files

libbinder: include full error if cannot init

We've seen a few cases of the "Binder driver could not be opened" error
appearing in production, but in most of these contexts, we don't
actually have access to the full logs (we only have the tombstone).
However, all of the different errors that could happen (running out of
FDs, failure to mmap, etc..) would be logged previously. Now, the error
is kept, and it is included in the tombstone.

Bug: 197637414 (and many others)
Test: boot, binderLibTest
Test: manually verify error is printed (we don't have an existing test to put this in because
  ProcessState can only be initialized once):
    Binder driver '/dev/null' could not be opened. Terminating: Binder ioctl to obtain version failed: Inappropriate ioctl for device
Change-Id: I636f1c5bfa9c8932e3db3d84af46ce3b0f1e98bc
parent 78b7e384
Loading
Loading
Loading
Loading
+54 −48
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <binder/ProcessState.h>

#include <android-base/result.h>
#include <binder/BpBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -384,22 +385,23 @@ String8 ProcessState::getDriverName() {
    return mDriverName;
}

static int open_driver(const char *driver)
{
static base::Result<int> open_driver(const char* driver) {
    int fd = open(driver, O_RDWR | O_CLOEXEC);
    if (fd >= 0) {
    if (fd < 0) {
        return base::ErrnoError() << "Opening '" << driver << "' failed";
    }
    int vers = 0;
    status_t result = ioctl(fd, BINDER_VERSION, &vers);
    if (result == -1) {
            ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
        close(fd);
            fd = -1;
        return base::ErrnoError() << "Binder ioctl to obtain version failed";
    }
    if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
          ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
                vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
        close(fd);
            fd = -1;
        return base::Error() << "Binder driver protocol(" << vers
                             << ") does not match user space protocol("
                             << BINDER_CURRENT_PROTOCOL_VERSION
                             << ")! ioctl() return value: " << result;
    }
    size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
    result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
@@ -411,41 +413,45 @@ static int open_driver(const char *driver)
    if (result == -1) {
        ALOGV("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
    }
    } else {
        ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
    }
    return fd;
}

ProcessState::ProcessState(const char* driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mWaitingForThreads(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
    , mCallRestriction(CallRestriction::NONE)
{
    if (mDriverFD >= 0) {
      : mDriverName(String8(driver)),
        mDriverFD(-1),
        mVMStart(MAP_FAILED),
        mThreadCountLock(PTHREAD_MUTEX_INITIALIZER),
        mThreadCountDecrement(PTHREAD_COND_INITIALIZER),
        mExecutingThreadsCount(0),
        mWaitingForThreads(0),
        mMaxThreads(DEFAULT_MAX_BINDER_THREADS),
        mStarvationStartTimeMs(0),
        mThreadPoolStarted(false),
        mThreadPoolSeq(1),
        mCallRestriction(CallRestriction::NONE) {
    base::Result<int> opened = open_driver(driver);

    if (opened.ok()) {
        // mmap the binder, providing a chunk of virtual address space to receive transactions.
        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE,
                        opened.value(), 0);
        if (mVMStart == MAP_FAILED) {
            close(opened.value());
            // *sigh*
            ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
            close(mDriverFD);
            mDriverFD = -1;
            opened = base::Error()
                    << "Using " << driver << " failed: unable to mmap transaction memory.";
            mDriverName.clear();
        }
    }

#ifdef __ANDROID__
    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver '%s' could not be opened.  Terminating.", driver);
    LOG_ALWAYS_FATAL_IF(!opened.ok(), "Binder driver '%s' could not be opened. Terminating: %s",
                        driver, opened.error().message().c_str());
#endif

    if (opened.ok()) {
        mDriverFD = opened.value();
    }
}

ProcessState::~ProcessState()