This is an exercise in "APUE" chapter 8(exercise 8.2, 2th edtion). The all discription is:
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.
In my program:
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;
}
I run the program, the output is:
main address: 4196560
f1 address: 4196604
f2 address: 4196663
f1 address: 4196604
[1] 12929 segmentation fault ./a.out
I am confused about the output.
- print
f1 address: xxx, we call vfork(), the child process runs first. - print
f2 address: xxx, then child process calls _exit(0). - main progress return from f1(), the stack frame of f1 was changed by f2, it may result segmentation fault.
But why print f1 address: 4196604 twice and why the address of f1 and f2 are not same?
I'm not sure what you mean by "the statck frame of f1 was changed by f2".
The code in
f2()is likely to segmentation fault in any case, regardless ofvfork().bufis uninitialized. There's no reason to believe it contains a null-terminated string. Therefore, the call tostrlen()could read off the end of the buffer.In any case, I'm not sure what you expect the loop to do. In the first iteration,
iis 0. If the call tostrlen()does not segfault, then the loop body stores 0 inbuf[0]. Therefore, on the next iteration of the loop,strlen(buf)will be 0,iwill be 1 (which is not less than 0), so the loop will terminate.The second print of
f1 address: 4196604is when the parent process continues after thevfork()-ed subprocess exits. The parent process continues and callsf1()which prints that.The numbers that you print are the addresses of
f1andf2themselves. Why would you expect the address off1to be the same as the address off2? They are not, so they print different addresses.On the other hand, the address of
f1is the same in the parent process and the subprocess, since the subprocess shares the parent's address space. So, the same address is printed forf1both times.