Shawn摘要

这两天在做myshell任务的时候,遇到了一个很诡异的问题,fork()出的子进程if(pid==0)无法printf(),调试也没有进入子进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
pid_t pid = fork();
if (pid < 0)
{
my_err("fork", __LINE__);
}

if (pid == 0)
{
printf("hellochild1");
// int infd = dup(0);
// int outfd = dup(1);
div_by_pipe(0, args_cnt);
// dup2(infd, STDIN_FILENO);
// dup2(outfd, STDOUT_FILENO);
printf("hellocchild2");
exit(0);
}

if (pid > 0)
{
waitpid(pid, NULL, 0);
printf("helloparent\n");
}

而另外写的一个test却可以执行printf()

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
pid_t pid=fork();
if(pid==0)
{
printf("im child");//程序小就可以执行
}
else if(pid>0)
{
printf("im parent");
}
return 0;
}

让我以为子进程压根就没有产生,然而在daz学长的电脑上却可以执行(让我一度开始相信玄学),在询问chatgpt,在网上查找大量资料后无果,在学长的帮助下我开始尝试execl(“/bin/ls”,”ls”,”-l”,NULL)发现可以执行,然后发现学长的电脑上pritnf(“hello\n”)加上了’\n’,我加上’\n’后也可以执行,用fflush(stdout)也可以执行,可能是缓冲区存在垃圾的原因.程序直接return是因为div_by_pipe()写的有问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
pid_t pid = fork();
if (pid < 0)
{
my_err("fork", __LINE__);
}

if (pid == 0)
{
printf("hellochild1\n"); // 加'\n'也可以打印
// fflush(stdout);//刷新缓冲区也可以打印
// execl("/bin/ls","ls","-l",NULL);//exec函数族都可以执行
// int infd = dup(0);
// int outfd = dup(1);
div_by_pipe(0, args_cnt);
// dup2(infd, STDIN_FILENO);
// dup2(outfd, STDOUT_FILENO);
printf("hellocchild2\n");
exit(0);
}

if (pid > 0)
{
waitpid(pid, NULL, 0);
printf("helloparent\n");
}

这不禁让我感慨编程没有玄学,翻译过来都是二进制语言,bug一定是有迹可循的