Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Android XCrash #28

Open
Open
@nzcv

Description

查找 xc_crash_child_notifier 的定义和使用位置。

[2 tools called]

查看更多上下文,了解完整的使用场景:

[3 tools called]

xc_crash_child_notifier 的作用

基本定义

xc_crash_child_notifier 是一个管道(pipe),用于在 i386 架构上使用 fork() 时,确保子进程已成功启动的同步机制。

代码位置和声明

// 第98行:声明为静态数组,存储管道的两个文件描述符
static int xc_crash_child_notifier[2];

初始化(第760行)

if(0 != pipe2(xc_crash_child_notifier, O_CLOEXEC)) return XCC_ERRNO_SYS;
  • 使用 pipe2() 创建管道
  • O_CLOEXEC:执行 exec 时自动关闭文件描述符

使用场景(第105-136行)

xc_crash_fork() 中,仅在 i386 架构上使用:

static int xc_crash_fork(int (*fn)(void *))
{
#ifndef __i386__
 // 非 i386 架构:使用 clone + CLONE_VFORK
 // CLONE_VFORK 会自动等待子进程完成
 return clone(fn, xc_crash_child_stack, CLONE_VFORK | CLONE_FS | CLONE_UNTRACED, NULL);
#else
 // i386 架构:使用 fork,需要手动同步
 pid_t dumper_pid = fork();
 if(-1 == dumper_pid)
 {
 return -1;
 }
 else if(0 == dumper_pid)
 {
 // 子进程:写入通知字符
 char msg = 'a';
 XCC_UTIL_TEMP_FAILURE_RETRY(write(xc_crash_child_notifier[1], &msg, sizeof(char)));
 syscall(SYS_close, xc_crash_child_notifier[0]);
 syscall(SYS_close, xc_crash_child_notifier[1]);
 _exit(fn(NULL));
 }
 else
 {
 // 父进程:读取通知字符,确保子进程已启动
 char msg;
 XCC_UTIL_TEMP_FAILURE_RETRY(read(xc_crash_child_notifier[0], &msg, sizeof(char)));
 syscall(SYS_close, xc_crash_child_notifier[0]);
 syscall(SYS_close, xc_crash_child_notifier[1]);
 return dumper_pid;
 }
#endif
}

工作原理

1. 子进程(第115-123行)

  • 写入一个字符('a')到管道的写端 [1]
  • 关闭管道的两端
  • 执行转储函数并退出

2. 父进程(第125-134行)

  • 从管道的读端 [0] 读取字符(阻塞直到子进程写入)
  • 读取成功后,确认子进程已启动
  • 关闭管道的两端
  • 返回子进程 PID

为什么需要这个机制?

架构差异

  • 非 i386(ARM/ARM64/x86_64):

    • 使用 clone() + CLONE_VFORK
    • CLONE_VFORK 会阻塞父进程直到子进程调用 exec()_exit()
    • 无需额外同步
  • i386:

    • 使用 fork()
    • fork() 后父子进程并发执行,无自动等待
    • 需要手动同步,确保子进程已启动

关键作用

  1. 同步保证:父进程在子进程启动后再继续
  2. 错误检测:如果子进程启动失败,父进程的 read() 可能失败或阻塞,便于发现异常
  3. 架构兼容:在 i386 上提供与 CLONE_VFORK 类似的同步效果

时序图

父进程 管道 子进程
 | | |
 |---fork()------------>| |
 | | |
 | |<---fork()返回0--------|
 | | |
 | |---write('a')-------->|
 | | |
 |<---read('a')---------| |
 | | |
 |---close()------------| |
 | |---close()------------|
 | | |
 |---return pid---------| |

总结

xc_crash_child_notifier 是一个用于 i386 架构的进程同步机制,通过管道确保父进程在子进程启动后再继续执行,弥补 fork() 缺少自动等待的差异,保证崩溃转储流程的可靠性。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

        AltStyle によって変換されたページ (->オリジナル) /