# Tracing System Calls at a High Level Ever call `f.write()` in Python and wonder what actually hits the kernel? This is a high-level trace of a write call as it crosses from user space into kernel space. ## Prerequisites ### User Space And Kernel Space Linux runs code in different privilege modes. Normal applications run in user space. The kernel runs in a more privileged mode and controls access to hardware and shared system resources. System calls are one of the main interfaces between those worlds. ### Traps A trap is a synchronous transfer of control from user space to the kernel. Unlike hardware interrupts, traps are caused by the running program itself. ## Step 1: User Space Calls Into A Syscall Wrapper When Python writes to a file, it eventually reaches a libc wrapper around `write`. That wrapper prepares the syscall number and arguments in the expected registers, then executes the CPU instruction used to enter the kernel. On x86-64 Linux, that interface is commonly the `syscall` instruction. ## Step 2: The Kernel Saves User Context On entry, the kernel saves user registers into a structure such as `pt_regs`. This saved register state lets the kernel: - Return to user space. - Restart syscalls when appropriate. - Deliver signals. - Preserve the user context while kernel work runs. ## Step 3: The Kernel Dispatches The Syscall The kernel reads the syscall number and dispatches to the correct handler. For a write path, this eventually reaches logic around `vfs_write`, where the kernel validates the file descriptor, copies data from user memory, and hands the write to the relevant filesystem or file implementation. ## Step 4: Control Returns To User Space After the kernel finishes the syscall, it places the return value in the expected register and returns control back to user space. For `write`, the return value is usually the number of bytes written or `-1` with `errno` set by the wrapper. ## What To Remember A syscall is not just a normal function call. It is a controlled transition across a privilege boundary: 1. User code prepares arguments. 2. The CPU enters kernel mode. 3. The kernel saves context. 4. The kernel dispatches the syscall. 5. The kernel validates memory and resources. 6. The kernel returns a result to user space. ## Related - [[File Descriptors Part 1]] - [[Field Notes/File Descriptor]] - [[Topics/Linux & Systems]]