system-callsstrace

strace ordering of system calls does not match expected order


I would expect strace run with the test code snippet to output the write call ahead of the open calls as suggested by the dissambly. Does puts perform the write asynchronously somehow or does strace reorder the output ?

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

int main() {
   close(1);
   printf("Interesting ordering\n");
   int fd = open("temp.txt", O_RDONLY);
   int fd1 = open("temp.txt", O_RDONLY);
}

Strace snippet:

munmap(0x7fe46ef45000, 115047)          = 0
close(1)                                = 0
newfstatat(1, "", 0x7fffeea1b980, AT_EMPTY_PATH) = -1 EBADF (Bad file descriptor)
getrandom("\x96\xa6\x6b\xd0\x3c\xde\x09\x28", 8, GRND_NONBLOCK) = 8
brk(NULL)                               = 0xb18000
brk(0xb39000)                           = 0xb39000
openat(AT_FDCWD, "temp.txt", O_RDONLY)  = 1
openat(AT_FDCWD, "temp.txt", O_RDONLY)  = 3
write(1, "Interesting ordering\n", 21)  = -1 EBADF (Bad file descriptor)
exit_group(0)                           = ?

Disassembly of main:

0000000000401146 <main>:
  401146:   55                      push   %rbp
  401147:   48 89 e5                mov    %rsp,%rbp
  40114a:   48 83 ec 10             sub    $0x10,%rsp
  40114e:   bf 01 00 00 00          mov    $0x1,%edi
  401153:   e8 e8 fe ff ff          call   401040 <close@plt>
  401158:   bf 10 20 40 00          mov    $0x402010,%edi
  40115d:   e8 ce fe ff ff          call   401030 <puts@plt>
  401162:   be 00 00 00 00          mov    $0x0,%esi
  401167:   bf 25 20 40 00          mov    $0x402025,%edi
  40116c:   b8 00 00 00 00          mov    $0x0,%eax
  401171:   e8 da fe ff ff          call   401050 <open@plt>
  401176:   89 45 fc                mov    %eax,-0x4(%rbp)
  401179:   be 00 00 00 00          mov    $0x0,%esi
  40117e:   bf 25 20 40 00          mov    $0x402025,%edi
  401183:   b8 00 00 00 00          mov    $0x0,%eax
  401188:   e8 c3 fe ff ff          call   401050 <open@plt>
  40118d:   89 45 f8                mov    %eax,-0x8(%rbp)
  401190:   b8 00 00 00 00          mov    $0x0,%eax
  401195:   c9                      leave
  401196:   c3                      ret

Solution

  • The order shown by strace is correct: it is the order of the system calls, and not the library calls.

    The call to printf is usually buffered, and is not really written until you issue a fflush.

    The main problem with your code is that you are mixing calls from the stdio library with low-level calls such as write(); when you do that, the results are undefined and may surprise you.