A strong answer
A strong candidate frames How does strace intercept system calls? around the exact memory layout, compiler semantics, and hardware execution model covered in Dynamic System Call and Userspace Tracing: strace, ltrace, and kprobes. Explain ptrace-based tracing, SIGTRAP stop on syscall entry/exit, and how strace reads registers.
Systems software frequently fails or hangs without emitting meaningful error logs:
- A web server daemon fails on startup with
Configuration error: code 1, but does not name which configuration file or directory path triggered the failure. - A high-throughput database worker stalls with 0% CPU usage, completely unresponsive to incoming client requests.
- An application reports intermittent 500-millisecond latency spikes, but application-level logs show processing time as less than 1 millisecond.
When source code is complex, third-party libraries lack debug logs, or an issue only occurs in production environments where recompilation is impossible, debugging from the inside out is difficult.
In a production interview, always connect the specification rule to its concrete runtime consequence: state what lives on the stack versus the heap or static storage segment, how the compiler or operating system validates alignments, lifetimes, and error codes, and what happens under adversarial or boundary inputs (such as zero-length buffers, integer overflow, concurrent mutation, or partial I/O). Backing your explanation with a small trace of register/memory state transitions immediately separates senior systems engineers from candidates who only memorized syntax.
What the interviewer is listening for
- Mastery of core invariant: Trace process-kernel system call interactions and arguments using strace.
- Mastery of core invariant: Inspect dynamic shared library calls and parameter payloads using ltrace.
- Mastery of core invariant: Trace low-level breakpoint traps and register inspection via the ptrace system call.
- Hardware and ABI awareness: Explaining how sizes, alignments, calling conventions, or kernel boundaries behave on real 64-bit targets rather than relying on implementation-defined assumptions.
- Defensive engineering: Naming the exact compiler flags (
-Wall -Wextra -Werror), static analyzers, or runtime sanitizers (-fsanitize=address,undefined,thread) that verify correctness in CI.
Common mistakes
- Explaining only surface syntax without tracing the underlying memory addresses, ownership lifetime, or kernel/user-space state transitions.
- Assuming undefined behavior (such as signed overflow, uninitialized reads, strict-aliasing violations, or dangling pointers) will "just work" because it passed an unoptimized
-O0debug build. - Ignoring return codes, partial reads/writes, alignment padding, or cleanup paths when an allocation or syscall fails midway through a function.