gpt4 book ai didi

linux - 如果缓冲区太小无法容纳 read() 系统调用返回的读取数据,会发生什么情况?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:57:09 24 4
gpt4 key购买 nike

考虑下面的程序,程序执行时会发生什么?

 #include <fcntl.h>
#include <stdio.h>
#include <string.h>
main()
{
int fd;
char buf[256];
fd=open("/etc/passwd",O_RDONLY);
if(read(fd,buf,1024)<0)
printf("read fail\n");
printf("strlen%d:\n",strlen(buf));
}

我认为 read 系统调用会将 1024 字节从内核缓冲区复制到 buf,结果应该是“strlen:1024”

但是我在gcc 4.1中执行,结果是:

strlen:1024
segment fault

我想知道为什么会出现段错误?

至少,如果应该的话,为什么不在 read 系统调用中立即抛出段错误,而是在 printf "stelen:1024"之后抛出?

我们将不胜感激。

最佳答案

看起来您愿意将 1024 字节复制到堆栈分配的 256 字节缓冲区中。这导致 undefined behavior . 任何事情都可能发生。

在您的特定情况下,read() 愉快地写入您的缓冲区并覆盖部分堆栈,包括当前执行函数的返回地址。直到 main() 尝试返回到内存空间的未映射部分,然后您的程序出现段错误,才会发生任何严重的事情。

另请注意,正如 wildplasser 在他的评论中正确指出的那样,看起来被覆盖的堆栈部分仍然是零填充的,因此 strlen() 找到一个终止 \0 字符位于索引 1024 并且本身不会漫游到未映射的区域。

当然,这种行为是完全不可靠的,如果您稍微修改您的程序,甚至在同一程序的运行之间,这种行为可能会发生变化。

关于linux - 如果缓冲区太小无法容纳 read() 系统调用返回的读取数据,会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15860974/

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