Skip to content

ProcessState初始化

追踪 ProcessState 单例、驱动打开、协议协商、mmap 传输区、fork 保护与初始化失败边界。

基于android-17.0.0_r1
AndroidBinderProcessStateNative框架源码阅读

ProcessState初始化 ​

ProcessState 是 libbinder 进程级状态的 owner:它保存 Binder 驱动 fd、事务接收区映射、线程池计数、handle 到 BpBinder 的表以及 fork 状态。初始化不是简单的 C++ 单例构造,而是“选择 driver → call_once 竞争保护 → pthread_atfork 注册 → 打开并协商驱动 → mmap 接收区”的组合流程。

本文面向已经读过 Binder设备打开、Binder内存映射 和 ServiceManager启动 的读者。本文回答 self()、initWithDriver() 和 selfOrNull() 如何共享单例、驱动路径何时生效、初始化失败如何表现,以及 fork 后为什么不能继续使用原 ProcessState。线程池如何加入和处理事务由后续 Native 框架文章展开。

1. 入口选择 ​

1.1 默认驱动 ​

源码文件:frameworks/native/libs/binder/ProcessState.cpp

相关函数:self()、initWithDriver()、selfOrNull()、selfIfKernelBinderEnabled()

cpp
sp<ProcessState> ProcessState::self() {
    return init(kDefaultDriver, false /*requireDefault*/);
}

sp<ProcessState> ProcessState::initWithDriver(const char* driver) {
    return init(driver, true /*requireDefault*/);
}

sp<ProcessState> ProcessState::selfOrNull() {
    return init(nullptr, false /*requireDefault*/);
}

sp<ProcessState> ProcessState::selfIfKernelBinderEnabled() {
    if (access(kDefaultDriver, R_OK) == -1) return nullptr;
    return init(kDefaultDriver, false /*requireDefault*/);
}

普通构建的 kDefaultDriver 是 /dev/binder,VNDK 构建选择 /dev/vndbinder。selfOrNull() 的 null 参数表示只查询已有单例;selfIfKernelBinderEnabled() 先做设备节点可读性检查,但这只是访问门槛,不等于后续 open()、协议协商和 mmap 一定成功。

1.2 路径关系 ​

2. 单例竞争 ​

2.1 查询分支 ​

源码文件:frameworks/native/libs/binder/ProcessState.cpp

相关函数:ProcessState::init()

cpp
[[clang::no_destroy]] static sp<ProcessState> gProcess;
[[clang::no_destroy]] static std::mutex gProcessMutex;

sp<ProcessState> ProcessState::init(
        const char* driver, bool requireDefault) {
    if (driver == nullptr) {
        std::lock_guard<std::mutex> l(gProcessMutex);
        if (gProcess) verifyNotForked(gProcess->mForked);
        return gProcess;
    }
    ...
}

查询分支锁住全局 mutex 后读取 gProcess。它不会创建驱动 fd,也不会通过 access() 证明 Binder 当前可用;调用者得到的是“是否已经有对象”的答案。

2.2 初始化分支 ​

cpp
[[clang::no_destroy]] static std::once_flag gProcessOnce;
std::call_once(gProcessOnce, [&] {
    if (access(driver, R_OK) == -1) {
        ALOGE("Binder driver %s is unavailable. Using /dev/binder instead.",
              driver);
        driver = "/dev/binder";
    }

    int ret = pthread_atfork(ProcessState::onFork,
                             ProcessState::parentPostFork,
                             ProcessState::childPostFork);
    LOG_ALWAYS_FATAL_IF(ret != 0,
                        "pthread_atfork error %s", strerror(ret));

    std::lock_guard<std::mutex> l(gProcessMutex);
    gProcess = sp<ProcessState>::make(driver);
});

call_once 保证 lambda 只执行一次;mutex 保护对象指针和 fork 回调安装顺序。驱动不可读时源码回退到 /dev/binder,但构造函数仍可能因为打开、版本或 mmap 失败而产生无效状态。

2.3 驱动一致性 ​

cpp
if (requireDefault) {
    LOG_ALWAYS_FATAL_IF(
            gProcess->getDriverName() != driver,
            "ProcessState was already initialized with %s, "
            "can't initialize with %s.",
            gProcess->getDriverName().c_str(), driver);
}
verifyNotForked(gProcess->mForked);
return gProcess;

initWithDriver() 要求调用必须发生在其他初始化之前;若单例已经用不同 driver 建立,路径不一致会 fatal。self() 的 requireDefault=false 不会主动切换已经存在的单例。

3. 驱动建立 ​

3.1 打开与协商 ​

源码文件:frameworks/native/libs/binder/ProcessState.cpp

相关函数:open_driver()

cpp
static unique_fd open_driver(
        const char* driver, String8* error) {
    auto fd = unique_fd(open(
            driver, O_RDWR | O_CLOEXEC));
    if (!fd.ok()) return {};

    int vers = 0;
    int result = ioctl(fd.get(), BINDER_VERSION, &vers);
    if (result == -1 ||
            vers != BINDER_CURRENT_PROTOCOL_VERSION) {
        return {};
    }

    size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
    result = ioctl(fd.get(), BINDER_SET_MAX_THREADS,
                   &maxThreads);
    if (result == -1) {
        ALOGE("Binder ioctl to set max threads failed: %s",
              strerror(errno));
    }
    return fd;
}

打开使用 O_RDWR | O_CLOEXEC。版本不匹配是失败;设置最大线程数失败只记录错误,fd 仍可返回。默认线程上限由 DEFAULT_MAX_BINDER_THREADS 初始化,后续进程代码仍可调用 setThreadPoolMaxThreadCount() 调整策略。

3.2 特性启用 ​

cpp
uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
result = ioctl(fd.get(), BINDER_ENABLE_ONEWAY_SPAM_DETECTION,
               &enable);
if (result == -1) {
    ALOGE_IF(ProcessState::isDriverFeatureEnabled(
                     ProcessState::DriverFeature::ONEWAY_SPAM_DETECTION),
             "Binder ioctl to enable oneway spam detection failed: %s",
             strerror(errno));
}

oneway spam detection 的 ioctl 失败不一定让打开流程失败:只有当 binderfs feature 文件表明驱动支持该能力时才记录错误。这里的“可选特性失败”与协议版本失败是不同级别。

4. 接收映射 ​

4.1 构造状态 ​

源码文件:frameworks/native/libs/binder/ProcessState.cpp

相关函数:ProcessState::ProcessState()

cpp
ProcessState::ProcessState(const char* driver)
      : mDriverName(String8(driver)),
        mDriverFD(-1),
        mVMStart(MAP_FAILED),
        mMaxThreads(DEFAULT_MAX_BINDER_THREADS),
        mCurrentThreads(0),
        mKernelStartedThreads(0),
        mForked(false),
        mThreadPoolStarted(false),
        mThreadPoolSeq(1),
        mCallRestriction(CallRestriction::NONE) {
    String8 error;
    unique_fd opened = open_driver(driver, &error);
    ...
}

构造函数先把 fd、映射和线程状态置于可识别的初始值,再尝试建立 driver。mVMStart=MAP_FAILED 让析构可以区分“没有映射”与有效地址。

4.2 mmap失败 ​

cpp
if (opened.ok()) {
    mVMStart = mmap(nullptr, BINDER_VM_SIZE,
                    PROT_READ,
                    MAP_PRIVATE | MAP_NORESERVE,
                    opened.get(), 0);
    if (mVMStart == MAP_FAILED) {
        ALOGE("Using %s failed: unable to mmap transaction memory.",
              driver);
        opened.reset();
        mDriverName.clear();
    }
}

Binder 接收区是用户态地址空间预留,权限为 PROT_READ,内核通过同一 fd 管理事务页。mmap 失败会关闭临时 fd 并清空 driver 名;Android 构建下 EXPECT_BINDER_OPEN_SUCCESS 还会让打开失败 fatal,host 构建则记录错误后保留对象。

5. Fork保护 ​

5.1 atfork回调 ​

源码文件:frameworks/native/libs/binder/ProcessState.cpp

相关函数:onFork()、parentPostFork()、childPostFork()

cpp
void ProcessState::onFork() {
    gProcessMutex.lock();
}

void ProcessState::parentPostFork() {
    gProcessMutex.unlock();
}

void ProcessState::childPostFork() {
    if (gProcess) {
        gProcess->mForked = true;
        close(gProcess->mDriverFD);
        gProcess->mDriverFD = -1;
    }
    gProcessMutex.unlock();
}

子进程继承了用户态对象和映射状态,却不能安全地继续复用父进程 Binder 状态。子 fork 回调关闭 fd 并标记 mForked;之后任何入口调用 verifyNotForked() 都 fatal。

5.2 初始化时机 ​

pthread_atfork() 必须在创建 gProcess 前安装,否则另一个线程可能在回调安装前 fork,产生没有 fork 保护的 ProcessState。这个顺序是并发安全的一部分,不是初始化风格偏好。

6. 生命周期边界 ​

6.1 线程池字段 ​

源码文件:frameworks/native/libs/binder/include/binder/ProcessState.h

相关字段:mMaxThreads、mCurrentThreads、mKernelStartedThreads、mThreadPoolStarted

初始化只建立计数和 fd,不自动启动用户态线程池。startThreadPool()、joinThreadPool() 或 polling 由进程主线决定;因此 ProcessState 存在不等于已经能消费 Binder transaction。

6.2 析构清理 ​

cpp
ProcessState::~ProcessState() {
    if (mDriverFD >= 0) {
        if (mVMStart != MAP_FAILED) {
            munmap(mVMStart, BINDER_VM_SIZE);
        }
        close(mDriverFD);
    }
    mDriverFD = -1;
}

析构先解除映射,再关闭 fd。全局 gProcess 使用 no_destroy,正常进程退出时通常不会走普通单例析构;这段代码主要为显式生命周期和测试提供资源释放逻辑。

7. 源码验证 ​

7.1 入口搜索 ​

bash
rg -n "ProcessState::(self|selfOrNull|initWithDriver|init)|pthread_atfork|call_once" \
  frameworks/native/libs/binder/ProcessState.cpp

rg -n "open_driver|BINDER_VERSION|BINDER_SET_MAX_THREADS|mmap|BINDER_VM_SIZE" \
  frameworks/native/libs/binder/ProcessState.cpp

rg -n "onFork|parentPostFork|childPostFork|verifyNotForked" \
  frameworks/native/libs/binder/ProcessState.cpp

7.2 证明边界 ​

固定源码范围没有把 ProcessState 的所有初始化分支包装成一个直接生产单元测试;本文的关键结论分别由静态控制流、驱动 ioctl 分支、构造/析构清理和 ServiceManager 启动调用共同支撑。读者可以用以下问题检查理解:为什么 selfOrNull() 不会创建对象,为什么 initWithDriver() 不能晚于 self(),为什么 mmap 失败必须关闭 fd,以及 fork 后为什么关闭 fd 还不够、仍需 mForked fatal 保护。