Course contentsShow
← Linux
Lesson 1545 of 1,81913. Containerization Primitives and NamespacesFree lesson

Kernel Stack Unwinding

Interpret kernel stack traces when a process crashes within a restricted cgroup environment.

In this lesson, you will learn how to reconstruct the chain of kernel function calls leading up to a crash within a containerized environment by interpreting the kernel stack.

Understanding the Kernel Stack

When a process triggers a kernel-mode exception—such as a page fault inside a restricted cgroup—the CPU pushes the current execution state onto a per-task kernel stack. "Unwinding" is the process of traversing this stack to determine the series of function calls that reached the point of failure.

In containerized environments, these traces are vital because the stack often contains information about resource limits (like cgroup-specific memory reclaim paths) or namespace-specific operations that triggered the fault.

Interpreting the Trace

A kernel stack trace typically looks like this:

[<ffffffff81234567>] ? do_page_fault+0x123/0x450
[<ffffffff81234890>] ? page_fault+0x1e/0x30
[<ffffffff81098765>] ? mem_cgroup_charge_statistics+0x45/0x90
[<ffffffff81098abc>] ? mem_cgroup_try_charge+0x110/0x300

To unwind this manually or via tooling, the kernel uses metadata stored in the .eh_frame or specialized DWARF sections. When debugging a crash inside a container, you must look for "cgroup-aware" functions in the stack trace. If a process crashes while under high memory pressure, you will likely see mem_cgroup_* functions at the top of the stack, indicating that the task was blocked or faulted while attempting to account for memory within its assigned cgroup.

The Challenge of Inlined Functions

Modern kernels aggressively inline functions to improve performance. When you see an unwound stack, some expected functions might be missing because the compiler optimized them away. If your trace shows a function but skips its parent, check if the instruction pointer (RIP) lands in an inlined block. When analyzing these in a restricted environment, focus on the transition between generic kernel code and cgroup-specific helpers—this is usually where namespace-specific configuration hits global kernel logic, triggering the underlying fault.

Key Takeaway: Kernel stack unwinding reconstructs the call path of a process, allowing you to identify if a crash occurred due to generic kernel logic or cgroup-specific resource enforcement.