Why fseek causes a read()?

Konstantin Kharlamov hi-angel@yandex.ru
Thu Jan 30 23:29:00 GMT 2020


I was debugging a hang of hexdump utility with high CPU load, when 
trying to print a piece of block device somewhere around ≈0x80000000 offset.

Long story short: the problem came down to the libc implementation of 
fseek(). When called with SEEK_SET argument, for some reason it does two 
things, in this order:

1. lseek() called with SEEK_SET
2. read() called, which reads everything lseek just skipped (so e.g. for 
my problem with reading at 0x80000000 it would have to read around half 
a terabyte before returning)

I haven't found anything in documentation for `fread()` about having to 
do the read, nor anything came up in search engine. So unless I'm 
missing something, it looks like some odd bug in fseek.

P.S. Example how to reproduce: save the following code as test.c, and 
run it under `strace` utility. You'll see 30 bytes of `test.cpp` being 
read just after lseek call at the end.

     #include <fcntl.h>
     #include <stdio.h>

     int main() {
         FILE* f = fopen("/tmp/test.cpp", "r");
         if (!f)
             perror("");
         fseek(f, 30, SEEK_SET);
     }



More information about the Libc-help mailing list