0

我正在制作一个库,它被注入进程并重新定义一些函数,例如 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);
}

在上面的函数中,对 open(2) 的调用是否会因为我调用了 mmap(2) 而受到影响?

4

2 回答 2

1

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

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

于 2019-05-24T22:13:43.953 回答
1

是的。

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

响应问题更新:如果问题中提供的函数被称为信号处理程序,则由于调用mmap(). 该UB的细节无法预测,至少不能从相关标准中预测。这就是“未定义”的意思。没有任何理由假设open()通话的实际和明显效果会以某种方式受到保护而不受干扰。也不是一般的信号处理机制。程序中也没有其他任何内容。

你离 UB 的轨迹越远,任何明显的影响就越不可能,操作系统就越有可能包含它,但 UB 不是什么好东西。原则上,它可能表现为您计算机能力范围内的任何行为或行为,例如擦除磁盘、关闭 CPU 风扇或将密码邮寄给黑客。

于 2019-05-24T22:13:47.833 回答