我有一个很有趣的问题,我想和你分享一下。
我把它压缩到最小的程序:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int cmd_left(char *name)
{
pid_t pid;
int f_d;
if ((pid = fork()) == -1)
{
perror("");
exit(1);
}
f_d = open(name);
printf("%dn", f_d);
close(f_d);
}
int main(int ac, char **av, char **env)
{
char **dummy_env;
if (ac < 2)
return (0);
dummy_env = malloc(10);
cmd_left(av[1]);
}
基本上,如果我删除malloc,打开工作正常。您只需要编译并给程序一个(有效的)文件就可以看到魔术。
open(2)
至少有两个参数。由于您只向它传递了一个参数,因此您调用了未定义行为。在这种情况下,open()
只是使用一些垃圾作为第二个参数。
您需要#include <fcntl.h>
在作用域中获得open()
的声明,然后告诉您没有使用足够的参数调用它:
int open(const char *filename, int flags, ...);
(可选参数-单数-如果在flags
参数中有O_CREAT
选项,则表示文件(mode_t perms
)的权限)
对malloc()
的调用会在足够的堆栈上涂鸦,以初始删除其上的零,这使得open()
的"额外参数"处于不为零的状态,并且您会遇到问题。
你调用的未定义行为可能导致任何奇怪的结果。
确保你至少使用' gcc -Wall
'编译,我建议使用' gcc -Wmissing-prototypes -Wstrict-prototypes -Wall -Wextra
'。
open
的头文件缺失,open期望至少有第二个参数