【发布时间】:2012-07-02 21:50:26
【问题描述】:
我安装了一个 SIGSEV 和 SIGABRT 信号处理程序,它派生出一个子进程: 1. 使用 SIGSTOP 停止其父进程。 2. 在父进程上调用 gdb 以收集崩溃诊断信息。
问题是,fork is not async signal safe on glibc 感谢 ptmalloc 安装了 pthread_atfork 处理程序。现在我的信号处理程序可能会冻结,因为 fork() 会尝试分配内存,这反过来可能会获取已锁定的互斥锁。
我想通过直接调用 fork 系统调用、绕过任何 libc 包装器并因此绕过任何 atfork 处理程序来解决这个问题。我怎么做?以下代码适用于 Linux,但似乎不适用于 OS X。它总是返回子 PID,从不为 0,还是应该这样做?我也不确定我是否正确捕获了返回值,因为定义是 int syscall(...) 但 fork 返回一个类型为 pid_t 的整数。
pid = syscall(SYS_fork);
我的应用可以在许多平台上运行,包括 Linux 和 OS X。
编辑:修正错字:s/thread safe/async signal safe/。
【问题讨论】:
-
抱歉,如果您的应用程序应该在许多平台上运行,我看不出调用依赖于平台的
syscall()对您有什么帮助... -
为什么不为
fork()编写一个包装器,在调用周围锁定/解锁互斥体,使其成为线程安全的? -
据我了解您链接的错误,如果您从信号处理程序调用
fork,而不是从不同的线程调用,这是相关的。也就是说,fork()不是异步信号安全的。没有提到它不是线程安全的。你受过这个错误吗?还是您只是格外小心? -
@FrédéricHamidi:我可以使用#ifdefs。
-
@Shahbaz:我不能,我无权访问 ptmalloc 的互斥锁。还有一个错字:我的意思是异步信号安全,而不是线程安全。