Master the fundamental concepts of system calls & kernel interface through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksstrace attaches to a process (or launches one) and prints each syscall with arguments and return values. It is the fastest way to see what a closed binary actually requests from the kernel.
Example line:
cLoading…
6 bytes written)= -1 EACCES signals failureFor example, comparing strace ls vs strace cat shows getdents64 directory reads versus sequential read on one file.
strace is the first tool SRE teams reach for when a production service mysteriously hangs on a file or socket operation, since it can reveal a blocked read() or a repeated ENOENT on a missing config file without recompiling anything. The -c summary mode you practice here is exactly what engineers use to spot syscall-count regressions, like a library that unexpectedly started calling stat() in a hot loop.
Before you call the implementation done, walk failure modes on purpose. Test empty structures, single-element edge cases, maximum concurrency, and errno paths that must not crash the program. OS code usually fails in production when happy-path tests pass but invariants break under contention or memory pressure.
Keep structures small and name fields after kernel counterparts when possible. That lets you read man pages and kernel source side by side while you work. Print observable events during development; remove noisy logs once tests pass reliably.
You will trace provided programs and answer questions about syscall counts and failure paths. The task asks you to correlate openat failures with errno values seen in application logs.
Rebuild strace -c: read the text output of strace -f -T and produce its summary table (time share, total seconds, microseconds per call, call and error counts per syscall), followed by an errno breakdown. Real traces are messy: multi-process prefixes, calls split by <unfinished ...>, signals, exit markers and lines without timing all have to be handled.
Optional option lines, then strace output:
cLoading…
[pid N] prefix. Skip empty lines, --- signal lines, +++ exit lines, and lines containing <unfinished ...>, because the call is counted when <... NAME resumed> completes it.[a-z0-9_] immediately followed by (, or with <... NAME resumed>, and it must contain ) = . Any other line is counted as unparsable.<S.UUUUUU> at the end of the line, in microseconds. A missing time counts as 0 (for example exit_group(0) = ?).-1 ERRNO is an error.% time is us * 100 / total, rounded half up to 2 decimals (all rows show 0.00 if the total is 0). usecs/call is us / calls, rounded down. The total row shows 100.00, or 0.00 if the total is 0.cLoading…
Column widths are 6, 11, 11, 9 and 9, separated by single spaces. The errors column is blank when it is 0. The errors: line lists errno names alphabetically, and appears only if there were errors. The unparsable-lines line appears only if there were any (1 unparsable line ignored for one).
Input:
cLoading…
Output:
cLoading…
Hidden tests cover strace -f traces with [pid N] prefixes, unfinished and resumed calls, signals and exits, unparsable lines, several errno kinds, sorting by name, timings above one second, and calls with no timing.