未定义为异步安全的函数(例如 mmap(2))是否会影响在信号处理程序中调用的其他异步安全函数?

Do functions which are not defined as async-safe, such as mmap(2), effect other async-safe functions called in signal handler?

我正在制作一个库,它被注入到进程中并重新定义了一些函数,例如 open(2) 以在调用真正的 open(2) 之前完成一些任务。我的图书馆会调用 mmap(2)。由于 open(2) 是异步安全的,是否有可能使用该库的人在信号处理程序中调用 open(2) 并且我的库还添加了对 mmap(2) 的调用可能会使他对 open(2) 的调用出错?

更新问题:

void handle_sigint(int sig)
{
    int fd = open(“file”, O_RDWR, 0666);
    void *base = mmap(NULL, 20, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
}

在上面的函数中,会不会因为我调用了mmap(2)而调用了open(2)呢?

完全有可能。另一个冲突是 main 上的 mmap() 运行 被 sighandler 中断,它调用 open() 调用 mmap() 导致 mmap() 重新进入。

这里的大关键字是"reentrant":您在 sighandler 中使用的任何函数都必须是可重入的。这意味着,该函数仅操作堆栈数据,或者,如果它操作全局数据或状态,则它必须以原子方式进行。原子性是一项非常困难的成就,它伴随着必须处理的更可怕的副作用(即死锁,需要 rollback/restart 行为......如果你有任何 RDB 的经验,你应该知道)。在这种情况下,mmap() 是麻烦的源头,因为它不仅操作进程静态数据,而且跨进程静态数据。

是的。

如果您的替代 open() 调用的函数不是 async-signal-safe,那么信号处理程序调用您的函数是不安全的。它与 async-signal-safe 的标准函数具有相同的名称和签名是无关紧要的。它调用替换函数或其他 async-signal-safe 函数是无关紧要的。预期信号处理程序对不是 async-signal-safe 的函数的调用不会是 直接 是无关紧要的。

回答问题更新:如果问题中出现的函数被调用为信号处理程序,由于调用mmap()。无法预测该 UB 的详细信息,至少无法根据相关标准进行预测。这就是 "undefined" 的意思。没有理由假设 open() 调用的实际和明显效果会以某种方式受到保护免受干扰。也不是一般的 signal-handling 机制。程序中也没有任何其他内容。

你离 UB 的轨迹越远,任何明显影响的可能性就越小,OS 包含它的可能性就越大,但 UB 不是什么好惹的东西。原则上,它可能表现为您的计算机能够产生的任何行为或行为,例如擦除您的磁盘、关闭您的 CPU 风扇或将您的密码邮寄给黑客。