我正在制作一个库,该库将注入到进程中并重新定义一些函数,例如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)的调用会受到影响吗?
答案 0 :(得分:1)
完全有可能。另一个冲突是主计算机上运行的mmap()被sighandler中断,该信号处理程序调用open(),后者调用mmap()导致mmap()重新进入。
这里的大关键字是“可重入”:您在sighandler中使用的任何函数都必须可重入。这意味着该函数仅操作堆栈数据,或者,如果操作全局数据或状态,则必须以原子方式进行操作。原子性是一个非常困难的成就,必须带来甚至更可怕的副作用(即死锁,回滚/重启行为的需要……如果您对RDB有任何经验,则应该知道)。在这种情况下,mmap()就是麻烦的源头,因为它不仅操纵流程静态数据,而且跨流程静态数据。
答案 1 :(得分:1)
是的
如果您的替代人open()
调用了一个异步信号安全的函数,那么信号处理程序调用您的函数并不安全。它与是异步信号安全的标准函数具有相同的名称和签名是无关紧要的。它调用替换函数或其他异步信号安全函数是无关紧要的。将来信号处理程序对不是异步信号安全的函数的调用不会是 direct 无关。
响应问题更新:如果问题中显示的函数被称为信号处理程序,则由于调用mmap()
,该函数具有不确定的行为。 UB的详细信息无法预测,至少不能从相关标准中预测。这就是“未定义”的意思。完全没有理由假设open()
调用的实际效果和明显效果会受到保护而不受干扰。也没有通用的信号处理机制。该程序中也没有其他内容。
您从UB的所在地获得的距离越远,任何明显的影响就越不可能,并且操作系统包含它的可能性也就越大,但是UB并不是一件容易的事。从原则上讲,它可能表现为计算机能力范围内的任何行为,例如擦拭磁盘,关闭CPU风扇或将密码邮寄给黑客。