我正在运行内核级别为3.0.76的32位SUSE Linux。
我可以看到我的代码中的stat()调用转换为strace输出中的stat64(),而没有指定任何CPP选项,如_LARGEFILE64_SOURCE或_FILE_OFFSET_BITS = 64。
#include<stdio.h>
#include<sys/stat.h>
int main ( int argc, char * argv[] )
{
char * path = "nofile";
struct stat b;
if (stat(path, &b) != 0) {
}
}
我用gcc编译了这个文件而没有编译器选项/标志。
在运行程序时,相关的strace输出为:
munmap(0xb770a000, 200704) = 0
stat64("nofile", 0xbfb17834) = -1 ENOENT (No such file or directory)
exit_group(-1)
任何人都可以告诉我stat()如何转换为stat64()?
提前致谢!
答案 0 :(得分:3)
答案似乎可以在stat手册页中找到
随着时间的推移,统计结构的规模增加了 stat()的三个连续版本:sys_stat()(slot __NR_oldstat), sys_newstat()(slot __NR_stat)和sys_stat64()(内核2.4中的新增内容; slot __NR_stat64)。 glibc stat()包装函数隐藏了这些 来自应用程序的详细信息,调用最新版本的 系统调用由内核提供,并重新打包返回的 旧二进制文件需要的信息。类似的评论适用于 fstat()和lstat()。
基本上,glibc总是调用stat64。
如果添加printf("%zu\n", sizeof b);
,struct stat
大小可能会有所不同,具体取决于您是否使用_FILE_OFFSET_BITS = 64,而glibc会在内核和代码之间转换struct stat
。
答案 1 :(得分:1)
我可以看到我的代码中的stat()调用转换为strace输出中的stat64()
您需要分析系统调用syscall统计信息的方式http://sourceware.org/glibc/wiki/SyscallWrappers(您可以看到此代码使用gdb
的一种方式:在gdb下执行此命令:catch syscall stat
当你的程序停止在这个断点上时,得到回溯并分析调用stat
的函数。
来自http://linux.die.net/man/2/stat64
随着时间的推移,统计结构的大小增加导致了 stat()的三个连续版本:sys_stat()(slot __NR_oldstat), sys_newstat()(slot __NR_stat)和sys_stat64()(内核2.4中的新增内容; slot __NR_stat64)。 glibc stat()包装函数隐藏了这些 来自应用程序的详细信息,调用最新版本的 内核提供的系统调用,并重新打包返回的 如果旧二进制文件需要,请提供信息。
因此glibc_wrapper根据sizeof(struct stat)决定它应该调用stat64的原因。