As Matthew said, strace uses the ptrace(2) system call to work its magic. ptrace is used to implement debuggers and other tools which need to inspect what another program is doing. Essentially, strace will call ptrace and attach to a target process.
Whenever the target process makes a system call, it will stop, and strace will be notified. strace will then inspect the registers and stack of the target process (also using ptrace) to determine what system call was being made (each call has a unique number, passed in a register) and what the arguments were. strace then resumes the process. When it returns from the system call, it is stopped, and strace is notified again, so it can inspect the return value. strace prints some information for the user each time this happens.
In response to your second question, a system call is different from a normal function call in that a system call is implemented in the kernel, while a regular function is implemented in userspace. That's a whole separate can of worms though.
strace works by using the ptrace system call which causes the kernel to halt the program being traced each time it enters or exits the kernel via a system call. The tracing program (in this case strace) can then inspect the state of the program by using ptrace.
strace gets the arguments to each system call depending on how that system works. On x86-64 systems, arguments to system calls are passed in CPU registers. In this case, strace can call ptrace with the PTRACE_GETREGS argument to get a copy of the register values and print them.
Syscalls are the interface between user and kernel space. See man 2 syscalls or syscalls.h for the list.
They should not be confused with standard C library functions, such as printf. These often end up calling a syscall, but not necessarily. Further, a user space program can call a syscall directly with the syscall function.
As Matthew said, strace uses the ptrace(2) system call to work its magic. ptrace is used to implement debuggers and other tools which need to inspect what another program is doing. Essentially, strace will call ptrace and attach to a target process.
Whenever the target process makes a system call, it will stop, and strace will be notified. strace will then inspect the registers and stack of the target process (also using ptrace) to determine what system call was being made (each call has a unique number, passed in a register) and what the arguments were. strace then resumes the process. When it returns from the system call, it is stopped, and strace is notified again, so it can inspect the return value. strace prints some information for the user each time this happens.
In response to your second question, a system call is different from a normal function call in that a system call is implemented in the kernel, while a regular function is implemented in userspace. That's a whole separate can of worms though.
I wrote a blog post about how strace works and an even longer blog post about how syscalls work.
strace
works by using theptrace
system call which causes the kernel to halt the program being traced each time it enters or exits the kernel via a system call. The tracing program (in this casestrace
) can then inspect the state of the program by usingptrace
.strace
gets the arguments to each system call depending on how that system works. On x86-64 systems, arguments to system calls are passed in CPU registers. In this case,strace
can callptrace
with thePTRACE_GETREGS
argument to get a copy of the register values and print them.Syscalls are the interface between user and kernel space. See man 2 syscalls or syscalls.h for the list.
They should not be confused with standard C library functions, such as
printf
. These often end up calling a syscall, but not necessarily. Further, a user space program can call a syscall directly with the syscall function.