In this lesson, you will learn how to trace the lifecycle of file handles to pinpoint exactly where your application fails to release system resources.
The Anatomy of a Leak
A file descriptor (FD) leak occurs when a process opens a file, socket, or pipe but fails to call close() before the handle falls out of scope or the task completes. Because the kernel maintains a strict limit on open files per process (defined by ulimit -n), leaked FDs eventually trigger "Too many open files" errors, leading to application crashes or silent failures.
To detect a leak, we must correlate the creation of a handle with its destruction. We look for "orphaned" handles—those that appear in the system’s open file table without a corresponding closure event in the trace logs.
Tracing the Lifecycle
We use dynamic tracing (such as ebpf or kprobes) to hook into the syscall entry and exit points for open and close. By capturing the stack trace whenever an FD is allocated, we can map it back to the specific line of code responsible for the leak.
Consider this logic flow for a tracer:
- Hook
sys_open/sys_openat: Capture the process ID (PID), the returned FD value, and the call stack. - Hook
sys_close: Capture the PID and the FD being closed. - Compare: Periodically scan the kernel’s internal file table for processes (via
/proc/<pid>/fd/) and compare the current list against your history of tracked "open" events.
// Conceptual trace point logic
TRACEPOINT_PROBE(syscalls, sys_enter_openat) {
// Record PID and timestamp associated with this specific file path
record_open_event(args->pid, args->filename);
}
TRACEPOINT_PROBE(syscalls, sys_exit_close) {
// Match the closed FD to the original open event; if no match exists, flag a potential double-close or leak
resolve_and_remove_event(args->pid, args->fd);
}
If you observe an increasing count of unclosed FDs associated with a specific code path—such as a loop that opens a configuration file but skips the close statement during an error-handling branch—you have successfully identified your leak vector.
Key Takeaway: To resolve FD leaks, perform differential analysis between system open and close syscalls to identify long-lived handles that lack a corresponding closure event.