2021年3月30日星期二

system call gives different behaviour between optimization levels

Recently I was playing with freebsd system calls I had no problem for i386 part since its well documented at here. But i can't find same document for x86_64.

I saw people are using same way like on linux but they use just assembly not c. I suppose in my case system call actually changing some register which is used by high optimization level so it gives different behaviour.

/* for SYS_* constants */  #include <sys/syscall.h>    /* for types like size_t */  #include <unistd.h>    ssize_t sys_write(int fd, const void *data, size_t size){      register long res __asm__("rax");      register long arg0 __asm__("rdi") = fd;      register long arg1 __asm__("rsi") = (long)data;      register long arg2 __asm__("rdx") = size;      __asm__ __volatile__(          "syscall"          : "=r" (res)          : "0" (SYS_write), "r" (arg0), "r" (arg1), "r" (arg2)          : "rcx", "r11", "memory"      );      return res;  }    int main(){      for(int i = 0; i < 1000; i++){          char a = 0;          int some_invalid_fd = -1;          sys_write(some_invalid_fd, &a, 1);      }      return 0;  }  

In above code I just expect it to call sys_write 1000 times then return main. I use truss to check system call and their parameters. Everything works fine with -O0 but when I go -O3 for loop getting stuck forever. I believe system call changing i variable or 1000 to something weird.

Dump of assembler code for function main:

0x0000000000201900 <+0>:     push   %rbp  0x0000000000201901 <+1>:     mov    %rsp,%rbp  0x0000000000201904 <+4>:     mov    $0x3e8,%r8d  0x000000000020190a <+10>:    lea    -0x1(%rbp),%rsi  0x000000000020190e <+14>:    mov    $0x1,%edx  0x0000000000201913 <+19>:    mov    $0xffffffffffffffff,%rdi  0x000000000020191a <+26>:    nopw   0x0(%rax,%rax,1)  0x0000000000201920 <+32>:    movb   $0x0,-0x1(%rbp)  0x0000000000201924 <+36>:    mov    $0x4,%eax  0x0000000000201929 <+41>:    syscall   0x000000000020192b <+43>:    add    $0xffffffff,%r8d  0x000000000020192f <+47>:    jne    0x201920 <main+32>  0x0000000000201931 <+49>:    xor    %eax,%eax  0x0000000000201933 <+51>:    pop    %rbp  0x0000000000201934 <+52>:    ret  

What is wrong with sys_write()? Why for loop getting stuck?

https://stackoverflow.com/questions/66878250/system-call-gives-different-behaviour-between-optimization-levels March 31, 2021 at 04:44AM

没有评论:

发表评论