Master the fundamental concepts of debugging mastery through this focused micro-challenge.
ptrace (process trace) is the Linux system call that underpins GDB, strace, and every other debugger on Linux. It allows one process to observe and control the execution of another process.
PTRACE_TRACEME: Child declares it should be traced by its parentPTRACE_PEEKDATA / PTRACE_POKEDATA: Read/write child memoryPTRACE_SINGLESTEP: Execute exactly one instructionPTRACE_CONT: Continue executionPTRACE_GETREGS / PTRACE_SETREGS: Read/write registersSetting breakpoints with INT3:
PTRACE_PEEKDATA0xCC (INT3) using PTRACE_POKEDATA0xCCYou will implement a simple debugger using ptrace that forks a child, sets a breakpoint, and single-steps. Building a minimal debugger from scratch teaches you exactly what GDB does under the hood when you set a breakpoint or step through code.
The parent calls waitpid after each PTRACE_CONT or PTRACE_SINGLESTEP. When the child stops on SIGTRAP (breakpoint hit), the parent reads registers with PTRACE_GETREGS, inspects state, and decides whether to continue or step. GDB wraps this loop with user-friendly commands, but the ptrace syscall sequence is identical. Security policies like YAMA ptrace_scope restrict which processes can be traced on hardened systems.
Write a C program that implements a simple debugger using ptrace. The parent process attaches to a child, sets a breakpoint, single-steps, and continues.
Requirements:
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
All starter code and reference implementations are available for your local setup.
View on Github