Does Julia's Linux platform support ever call syscalls directly?

I’m curious about whether Julia’s (or stdlib) Linux-specific parts ever call syscalls directly (without libc involvement)? Does Linux specific code even exist in the implementation of Julia or its stdlib?

I’m not a Julia dev, but if you check the code in src/ against the system calls listed by man syscalls you will see quite a few are being used. For example, file related system calls in src/init.c, on non-Windows systems:

#if defined(_OS_WINDOWS_)
        CloseHandle(fd);
        fd = CreateFile("NUL", readable ? FILE_GENERIC_READ : FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES,
                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
#else
        {
            int nullfd;
            nullfd = open("/dev/null", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH /* 0666 */);
            assert(nullfd != -1);
            dup2(nullfd, fd);
            close(nullfd);
        }
#endif

Or mmap():

gc.c:    void *pool = mmap(0, GC_PERM_POOL_SIZE, PROT_READ | PROT_WRITE,
gc-pages.c:    char *mem = (char*)mmap(0, pages_sz, PROT_READ | PROT_WRITE,
gc-pages.c:        // boundary if mmap didn't already do so.
gc-pages.c:        fprintf(stderr, "%d jl_gc_try_alloc_pages() %d mmap %d -> 0x%016x (0x%016x)\n", pthread_self(), pg_cnt, pages_sz, mem, mem_saved);
gc-stacks.c:    void* stk = mmap(0, bufsz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
safepoint.c:    char *addr = (char*)mmap(0, pgsz * 3, PROT_READ,
signals-unix.c:    else if (sig == SIGSEGV && info->si_code == SEGV_ACCERR && is_write_fault(context)) {  // writing to read-only memory (e.g., mmap)
signals-unix.c:        jl_errorf("fatal error allocating signal stack: mmap: %s", strerror(errno));
signals-win.c:                if (ExceptionInfo->ExceptionRecord->ExceptionInformation[0] == 1) { // writing to read-only memory (e.g. mmap)
sys.c:JL_DLLEXPORT void *jl_mmap(void *addr, size_t length, int prot, int flags,
sys.c:    return mmap(addr, length, prot, flags, fd, (off_t)offset);
task.c:                // fall back to stack copying if mmap fails

These are not specifically Linux-specific calls, btw, but definitely POSIX-specific.

I asked about direct syscalls (without going through libc):

I noticed, but in most cases the wrapper in glibc is pretty thin (and e.g. open() is definitely closer to a syscall that fopen()). Also, why would you expect a programming language like Julia to ever invoke a syscall other than through glibc? I would only expect kernel code or embedded systems code to ever do that.

Grepping the Julia source for syscall() shows at least this one:

$ cat src/jlapi.c
...
#ifdef _OS_LINUX_
static void rr_detach_teleport(void) {
#define RR_CALL_BASE 1000
#define SYS_rrcall_detach_teleport (RR_CALL_BASE + 9)
    int err = syscall(SYS_rrcall_detach_teleport, 0, 0, 0, 0, 0, 0);
    if (err < 0 || jl_running_under_rr(1)) {
        jl_error("Failed to detach from rr session");
    }
}
#endif
...
1 Like

Also, why would you expect a programming language like Julia to ever invoke a syscall other than through glibc? I would only expect kernel code or embedded systems code to ever do that.

Golang does that. It used not to depend on libc at all, but then added a libc dependency only for DNS resolution, as far as I remember.

BTW, I’m actually more interested in whether raw syscalls ever happen in Julia code (.jl files), rather than C or C++ code.

Seems there’s some testing code that does this:

$ cat src/test/threads.jl
...
# issue #34415 - make sure external affinity settings work
if Sys.islinux()
    const SYS_rrcall_check_presence = 1008
    global running_under_rr() = 0 == ccall(:syscall, Int,
        (Int, Int, Int, Int, Int, Int, Int),
        SYS_rrcall_check_presence, 0, 0, 0, 0, 0, 0)
else
    global running_under_rr() = false
end
...
2 Likes

This is actually a really interesting example (although not at all what I was looking for). The syscall is actually not a Linux syscall, rather it is emulated by the rr debugging tool: rr/syscalls.py at master · rr-debugger/rr · GitHub

1 Like