Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
While using drgn for debugging a linux vmcore, a stack trace was found to contain a single frame of "0: 0x0". It seemed peculiar since the corresponding panic dump in kmsg showed a stack trace of multiple frames with resolved symbols. Digging into the drgn stack unwinding functions, it was found that there was no way of handling a program counter (RIP on x86) of zero. The main unwinding function would return an error leading to an attempt to call a fallback unwind function. Even though the fallback routine was attempted, it did not help since the fallback tries to make use of frame pointers. In the case where the kernel is compiled without frame pointers, the fallback function would also error out due to an attempt to read from an unmapped register. A program counter of zero can be assumed to be a call to a null function pointer. Using this as a basis, when in the absence of frame pointers, the call to a null address can be unwound in a special way. Registers can be slightly adjusted so that unwinding is possible. First, the program counter needs to point somewhere it can be unwound. At the time of the null call, RSP will contain the return address so if we take that RSP and assign it to RIP, we effectively put the program counter after the null call. Next, the top of the stack frame needs to change to the top of the calling frame. This is done by incrementing RSP. At this point, unwinding can continue and any frames below the null call will be included in the trace. This special unwinding operation is done in the new function "unwind_call()". To solve the problem of being unable to handle a zero pc when frame pointers are not present, the fallback unwind function is updated to check for a zero pc and call the new function if needed. Signed-off-by: JP Kobryn <[email protected]>
- Loading branch information