這是「APUE」第8章練習(習題8.2,第2版)。全部解釋爲:在函數中調用vfork(),對結果感到困惑
回想一下圖7.6中的典型內存排列。由於與每個函數調用相對應的堆棧幀 通常存儲在堆棧中,並且因爲子進程在父級的地址空間中運行,所以如果調用vfork 來自除main之外的函數並且孩子在vfork之後會從這個函數返回嗎?編寫一個測試程序來驗證這一點,並畫出發生的事情。
在我的程序:
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
我感到困惑的輸出。
- print
f1 address: xxx
,我們調用vfork(),子進程先運行。 - print
f2 address: xxx
,然後子進程調用_exit(0)。 - f1()的主進度返回值,f1的堆棧幀被f2修改,可能導致分段錯誤。
但是爲什麼打印f1 address: 4196604
兩次,爲什麼f1和f2的地址不一樣?
'buf'未初始化所以'strlen的(BUF)'是未定義的行爲(也可能是段錯誤的原因)。那是故意的嗎? – rici 2015-04-05 05:23:08
是vfork在您的平臺上fork()的別名? – hd1 2015-04-05 05:40:03
@rici sizeof(buf)是一樣的 – 2015-04-05 05:51:23