gpt4 book ai didi

在函数中调用 vfork(),对结果感到困惑

转载 作者:行者123 更新时间:2023-11-30 17:17:13 26 4
gpt4 key购买 nike

这是“APUE”第 8 章中的练习(练习 8.2,第 2 版)。所有描述是:

Recall the typical arrangement of memory in Figure 7.6. Because the stack frames corresponding to each function call are usually stored in the stack, and because after a vfork the child runs in the address space of the parent, what happens if the call to vfork is from a function other than main and the child does a return from this function after the vfork? Write a test program to verify this, and draw a picture of what’s happening.

在我的程序中:

static void f1(void), f2(void);

int main(void) {
printf("main address: %d\n", main);
f1();
f2();
_exit(0);
}

static void f1(void) {
printf("f1 address: %d\n", f1);
pid_t pid;

if ((pid = vfork()) < 0)
err_sys("vfork error");
}

static void f2(void) {
printf("f2 address: %d\n", f2);
char buf[1000];
int i;

for (i = 0; i < sizeof(buf); ++i)
buf[i] = 0;
}

我运行程序,输出是:

main address: 4196560
f1 address: 4196604
f2 address: 4196663
f1 address: 4196604
[1] 12929 segmentation fault ./a.out

我对输出感到困惑。

  1. 打印f1地址:xxx,我们调用vfork(),子进程先运行。
  2. 打印f2地址:xxx,然后子进程调用_exit(0)。
  3. 从f1()返回主进程,f1的栈帧被f2改变,可能会导致段错误。

但是为什么打印f1地址:4196604两次并且为什么f1和f2的地址不相同?

最佳答案

我不确定“f1 的 statck 帧被 f2 更改”是什么意思。

无论vfork()如何,f2()中的代码在任何情况下都可能出现段错误。 buf 未初始化。没有理由相信它包含以空结尾的字符串。因此,对 strlen() 的调用可以读取缓冲区的末尾。

无论如何,我不确定您希望循环做什么。在第一次迭代中,i 为 0。如果对 strlen() 的调用没有出现段错误,则循环体将 0 存储在 buf[0].因此,在循环的下一次迭代中,strlen(buf)将为0,i将为1(不小于0),因此循环将终止.

第二次打印f1 address: 4196604是在vfork()-ed子进程退出后父进程继续运行的时候。父进程继续并调用 f1() 来打印该内容。

您打印的数字是 f1f2 本身的地址。为什么您期望 f1 的地址与 f2 的地址相同?它们不是,所以它们打印不同的地址。

另一方面,f1 的地址在父进程和子进程中是相同的,因为子进程共享父进程的地址空间。因此,f1 两次都会打印相同的地址。

关于在函数中调用 vfork(),对结果感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29454353/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com