系统调用stat()转换为stat64(),没有任何cpp选项

时间:2014-10-13 10:23:36

标签: c linux gcc gnu libc

我正在运行内核级别为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()?

提前致谢!

2 个答案:

答案 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的原因。