• Russ Cox's avatar
    runtime, syscall: work around FreeBSD/amd64 kernel bug · 555da73c
    Russ Cox authored
    The kernel implementation of the fast system call path,
    the one invoked by the SYSCALL instruction, is broken for
    restarting system calls. A C program demonstrating this is below.
    
    Change the system calls to use INT $0x80 instead, because
    that (perhaps slightly slower) system call path actually works.
    
    I filed http://www.freebsd.org/cgi/query-pr.cgi?pr=182161.
    
    The C program demonstrating that it is FreeBSD's fault is below.
    It reports the same "Bad address" failures from wait.
    
    #include <sys/time.h>
    #include <sys/signal.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    static void handler(int);
    static void* looper(void*);
    
    int
    main(void)
    {
            int i;
            struct sigaction sa;
            pthread_cond_t cond;
            pthread_mutex_t mu;
    
            memset(&sa, 0, sizeof sa);
            sa.sa_handler = handler;
            sa.sa_flags = SA_RESTART;
            memset(&sa.sa_mask, 0xff, sizeof sa.sa_mask);
            sigaction(SIGCHLD, &sa, 0);
    
            for(i=0; i<2; i++)
                    pthread_create(0, 0, looper, 0);
    
            pthread_mutex_init(&mu, 0);
            pthread_mutex_lock(&mu);
            pthread_cond_init(&cond, 0);
            for(;;)
                    pthread_cond_wait(&cond, &mu);
    
            return 0;
    }
    
    static void
    handler(int sig)
    {
    }
    
    int
    mywait4(int pid, int *stat, int options, struct rusage *rusage)
    {
            int result;
    
            asm("movq %%rcx, %%r10; syscall"
                    : "=a" (result)
                    : "a" (7),
                      "D" (pid),
                      "S" (stat),
                      "d" (options),
                      "c" (rusage));
    }
    
    static void*
    looper(void *v)
    {
            int pid, stat, out;
            struct rusage rusage;
    
            for(;;) {
                    if((pid = fork()) == 0)
                            _exit(0);
                    out = mywait4(pid, &stat, 0, &rusage);
                    if(out != pid) {
                            printf("wait4 returned %d\n", out);
                    }
            }
    }
    
    Fixes #6372.
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/13582047
    555da73c
Name
Last commit
Last update
..
asm_darwin_386.s Loading commit data...
asm_darwin_amd64.s Loading commit data...
asm_dragonfly_386.s Loading commit data...
asm_dragonfly_amd64.s Loading commit data...
asm_freebsd_386.s Loading commit data...
asm_freebsd_amd64.s Loading commit data...
asm_freebsd_arm.s Loading commit data...
asm_linux_386.s Loading commit data...
asm_linux_amd64.s Loading commit data...
asm_linux_arm.s Loading commit data...
asm_netbsd_386.s Loading commit data...
asm_netbsd_amd64.s Loading commit data...
asm_netbsd_arm.s Loading commit data...
asm_openbsd_386.s Loading commit data...
asm_openbsd_amd64.s Loading commit data...
asm_plan9_386.s Loading commit data...
asm_plan9_amd64.s Loading commit data...
asm_windows_386.s Loading commit data...
asm_windows_amd64.s Loading commit data...
bpf_bsd.go Loading commit data...
consistency_unix_test.go Loading commit data...
creds_test.go Loading commit data...
dir_plan9.go Loading commit data...
dll_windows.go Loading commit data...
env_plan9.go Loading commit data...
env_unix.go Loading commit data...
env_windows.go Loading commit data...
exec_bsd.go Loading commit data...
exec_linux.go Loading commit data...
exec_plan9.go Loading commit data...
exec_unix.go Loading commit data...
exec_windows.go Loading commit data...
lsf_linux.go Loading commit data...
mkall.sh Loading commit data...
mkerrors.sh Loading commit data...
mkerrors_windows.sh Loading commit data...
mksyscall.pl Loading commit data...
mksyscall_windows.pl Loading commit data...
mksysctl_openbsd.pl Loading commit data...
mksysnum_darwin.pl Loading commit data...
mksysnum_dragonfly.pl Loading commit data...
mksysnum_freebsd.pl Loading commit data...
mksysnum_linux.pl Loading commit data...
mksysnum_netbsd.pl Loading commit data...
mksysnum_openbsd.pl Loading commit data...
mksysnum_plan9.sh Loading commit data...
netlink_linux.go Loading commit data...
passfd_test.go Loading commit data...
race.go Loading commit data...
race0.go Loading commit data...
rlimit_linux_test.go Loading commit data...
route_bsd.go Loading commit data...
route_darwin.go Loading commit data...
route_dragonfly.go Loading commit data...
route_freebsd.go Loading commit data...
route_netbsd.go Loading commit data...
route_openbsd.go Loading commit data...
security_windows.go Loading commit data...
sockcmsg_linux.go Loading commit data...
sockcmsg_unix.go Loading commit data...
str.go Loading commit data...
syscall.go Loading commit data...
syscall_bsd.go Loading commit data...
syscall_darwin.go Loading commit data...
syscall_darwin_386.go Loading commit data...
syscall_darwin_amd64.go Loading commit data...
syscall_dragonfly.go Loading commit data...
syscall_dragonfly_386.go Loading commit data...
syscall_dragonfly_amd64.go Loading commit data...
syscall_freebsd.go Loading commit data...
syscall_freebsd_386.go Loading commit data...
syscall_freebsd_amd64.go Loading commit data...
syscall_freebsd_arm.go Loading commit data...
syscall_linux.go Loading commit data...
syscall_linux_386.go Loading commit data...
syscall_linux_amd64.go Loading commit data...
syscall_linux_arm.go Loading commit data...
syscall_netbsd.go Loading commit data...
syscall_netbsd_386.go Loading commit data...
syscall_netbsd_amd64.go Loading commit data...
syscall_netbsd_arm.go Loading commit data...
syscall_no_getwd.go Loading commit data...
syscall_openbsd.go Loading commit data...
syscall_openbsd_386.go Loading commit data...
syscall_openbsd_amd64.go Loading commit data...
syscall_plan9.go Loading commit data...
syscall_plan9_386.go Loading commit data...
syscall_plan9_amd64.go Loading commit data...
syscall_test.go Loading commit data...
syscall_unix.go Loading commit data...
syscall_windows.go Loading commit data...
syscall_windows_386.go Loading commit data...
syscall_windows_amd64.go Loading commit data...
syscall_windows_test.go Loading commit data...
types_darwin.go Loading commit data...
types_dragonfly.go Loading commit data...
types_freebsd.go Loading commit data...
types_linux.go Loading commit data...
types_netbsd.go Loading commit data...
types_openbsd.go Loading commit data...
types_plan9.c Loading commit data...
zerrors_darwin_386.go Loading commit data...
zerrors_darwin_amd64.go Loading commit data...
zerrors_dragonfly_386.go Loading commit data...
zerrors_dragonfly_amd64.go Loading commit data...
zerrors_freebsd_386.go Loading commit data...
zerrors_freebsd_amd64.go Loading commit data...
zerrors_freebsd_arm.go Loading commit data...
zerrors_linux_386.go Loading commit data...
zerrors_linux_amd64.go Loading commit data...
zerrors_linux_arm.go Loading commit data...
zerrors_netbsd_386.go Loading commit data...
zerrors_netbsd_amd64.go Loading commit data...
zerrors_netbsd_arm.go Loading commit data...
zerrors_openbsd_386.go Loading commit data...
zerrors_openbsd_amd64.go Loading commit data...
zerrors_plan9_386.go Loading commit data...
zerrors_plan9_amd64.go Loading commit data...
zerrors_windows.go Loading commit data...
zerrors_windows_386.go Loading commit data...
zerrors_windows_amd64.go Loading commit data...
zsyscall_darwin_386.go Loading commit data...
zsyscall_darwin_amd64.go Loading commit data...
zsyscall_dragonfly_386.go Loading commit data...
zsyscall_dragonfly_amd64.go Loading commit data...
zsyscall_freebsd_386.go Loading commit data...
zsyscall_freebsd_amd64.go Loading commit data...
zsyscall_freebsd_arm.go Loading commit data...
zsyscall_linux_386.go Loading commit data...
zsyscall_linux_amd64.go Loading commit data...
zsyscall_linux_arm.go Loading commit data...
zsyscall_netbsd_386.go Loading commit data...
zsyscall_netbsd_amd64.go Loading commit data...
zsyscall_netbsd_arm.go Loading commit data...
zsyscall_openbsd_386.go Loading commit data...
zsyscall_openbsd_amd64.go Loading commit data...
zsyscall_plan9_386.go Loading commit data...
zsyscall_plan9_amd64.go Loading commit data...
zsyscall_windows_386.go Loading commit data...
zsyscall_windows_amd64.go Loading commit data...
zsysctl_openbsd.go Loading commit data...
zsysnum_darwin_386.go Loading commit data...
zsysnum_darwin_amd64.go Loading commit data...
zsysnum_dragonfly_386.go Loading commit data...
zsysnum_dragonfly_amd64.go Loading commit data...
zsysnum_freebsd_386.go Loading commit data...
zsysnum_freebsd_amd64.go Loading commit data...
zsysnum_freebsd_arm.go Loading commit data...
zsysnum_linux_386.go Loading commit data...
zsysnum_linux_amd64.go Loading commit data...
zsysnum_linux_arm.go Loading commit data...
zsysnum_netbsd_386.go Loading commit data...
zsysnum_netbsd_amd64.go Loading commit data...
zsysnum_netbsd_arm.go Loading commit data...
zsysnum_openbsd_386.go Loading commit data...
zsysnum_openbsd_amd64.go Loading commit data...
zsysnum_plan9_386.go Loading commit data...
zsysnum_plan9_amd64.go Loading commit data...
zsysnum_windows_386.go Loading commit data...
zsysnum_windows_amd64.go Loading commit data...
ztypes_darwin_386.go Loading commit data...
ztypes_darwin_amd64.go Loading commit data...
ztypes_dragonfly_386.go Loading commit data...
ztypes_dragonfly_amd64.go Loading commit data...
ztypes_freebsd_386.go Loading commit data...
ztypes_freebsd_amd64.go Loading commit data...
ztypes_freebsd_arm.go Loading commit data...
ztypes_linux_386.go Loading commit data...
ztypes_linux_amd64.go Loading commit data...
ztypes_linux_arm.go Loading commit data...
ztypes_netbsd_386.go Loading commit data...
ztypes_netbsd_amd64.go Loading commit data...
ztypes_netbsd_arm.go Loading commit data...
ztypes_openbsd_386.go Loading commit data...
ztypes_openbsd_amd64.go Loading commit data...
ztypes_plan9_386.go Loading commit data...
ztypes_plan9_amd64.go Loading commit data...
ztypes_windows.go Loading commit data...
ztypes_windows_386.go Loading commit data...
ztypes_windows_amd64.go Loading commit data...