osandov/drgn

Python API for PRSTATUS

Closed this issue · 4 comments

A common question I get is "how to get the stack trace for a particular CPU?" -- mostly from people who are familiar with Crash's bt -c CPU command.

The correct answer is generally prog.stack_trace(cpu_curr(prog, CPU)). This is usually good enough, but I have an interesting edge case, again with my quest to make QEMU vmcores work nicely in Drgn.

When QEMU creates a vmcore, it doesn't know anything about the task on each CPU. Instead, it seems to just insert its internal ID number for that CPU into the pr_pid field (source). This means that, unless the PID on CPU happens to be the same as the QEMU CPU ID.... drgn won't decide that the PID matches the one you're looking for, and so it won't use the PRSTATUS value.

I can't think of a clean way to fix that: these numbers are totally valid PID values, and further, it's totally valid for them not to match. Maybe there would be a way to detect QEMU vmcores through a system of quirks, but that honestly sounds awful. It would be neat if there was some other way to just get a PRSTATUS object (or maybe convert it to a struct pt_regs ?) which could be passed into Program.stack_trace() so that we can see the CPU stack trace without needing to tie it to a particular task.

This could probably also be handled by having a Linux kernel helper for getting a stack trace from a CPU number. I wrote a quick implementation of that which worked great. I don't necessarily care about the PRSTATUS values as much as I do care about the reliable visibility into things that were on CPU.

I should also note that what I've seen is that the QEMU CPU ID seems to be a 1-based index. If we confirmed that would always be the case, we could probably detect when the PID fields collectively are 1, 2, 3, 4, ... from the PRSTATUS when we cache the notes. That seems like an unlikely case except maybe in some weird embedded system, and so we could assume that the vmcore was from QEMU and make the guess that the CPU PRSTATUS should probably be used for an on-cpu task.

1487db5 should make prog.stack_trace(cpu_curr(prog, CPU)) work as expected for QEMU dumps. Let me know if you get a chance to test it.

Just generated some fresh vmcores from QEMU and verified that prog.stack_trace(cpu_curr(prog, CPU)) works on my current vmcoreinfo branch based on your latest commit! I think we can close this then.