2016-08-05 106 views
-1

当我运行下面的代码为什么了vfork()给分段错误

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
int main() 
{ 
    pid_t pid; 
    pid = vfork(); 
    printf("hello world\n"); 
} 
Output: 
hello world 
hello world 
hello world 
Segmentation fault 

我知道,除非EXEC()或_exit()被调用,然后的vfork(),可以在陌生的方式表现,如果我们试图修改任何变量,但有人可以解释究竟发生了什么?为什么你好世界印刷3次?是否因为printf()被缓冲?最后为什么在父母试图返回时发生seg故障?

+2

如果你知道它正在调用一个未定义的行为,为什么你问具体的行为? –

+2

这是未定义行为的含义,它不能被解释,否则,它将被定义为 –

+0

“以一种奇怪的方式行事”并不是一个很好的表征“有未定义的行为”。特别是,不符合段错误的问题完全属于未定义行为的主要任意界限。因此,无论您的程序中是否存在可解释此类输出的任何代码,都要打印“hello world”三次。你不能合法地推断未定义的行为。 –

回答

1

(From POSIX.1)该了vfork()函数具有作为叉相同的效果(2), 不同之处在于,如果处理由 vfork的创建的行为是未定义的()要么修改比类型将为pid_t 的变量之外的任何数据用于存储vfork()的返回值,或从调用vfork()的函数中返回,或者在成功调用_exit(2)或exec(3)系列函数之一之前调用任何其他函数 函数 函数。

好像你违反全部使用vfork的条件。那么它不起作用。

0

的一块我写的代码是一场灾难,并会在一个不确定的行为方式,但这种行为的合理的解释可能是: -

由于地址空间是共享的,当孩子回来不通过_exit()exec(),因此将执行I/O缓冲区的刷新(这会导致额外的hello world语句),并且在清理过程中,当内存到printf()被释放时,它可能会将函数调用放在堆栈帧上,而父母仍然卡住。返回时,父可能没有任何返回地址返回给任何人,这会导致分段错误。