如果文件在 fopen(( 和 fgets(( 之间被覆盖会发生什么?我有一个程序因以下堆栈跟踪而失败:
0x00007f9d63629850 (Linux)
0x00007f9d6253e8ab (/lib64/libc-2.11.3.so) __memchr
0x00007f9d62523996 (/lib64/libc-2.11.3.so) _IO_getline_info_internal
0x00007f9d6252d0cd (/lib64/libc-2.11.3.so) __GI_fgets_unlocked
我有理由相信正在读取的文件可能在 fopen(( 和 fgets(( 之间被覆盖。这有多合理?
我们使用的是带有glibc 2.11.3的SUSE 11.4,所有更新和补丁都应用于glibc。
这取决于文件在磁盘上的覆盖方式。
- 如果文件被就地覆盖(相同的 inode(,您的程序将读取新数据。
fopen
不会在第一次读取之前自动填充缓冲区,因此fgets
将填充缓冲区并获取新数据(在并发更新后(。- 这主要适用于本地文件系统。 大多数网络文件系统都有优化,在没有文件锁定的情况下,可能仍会返回旧数据。
- 如果没有文件锁定,并发修改可能会导致观察中间状态的读取操作。
- 如果文件被替换(删除并重新创建,或使用重命名操作(,则将读取旧数据。