We need to have backtrace() / print_backtrace() et al. working from contexts without a kernel-supplied pt_regs to start from. This is needed for e.g. markers. See also bug #6580, bug #5085.
In the short term, it may be sufficient to jump over to the kernel's show_stack() routine (if configured & available -- runtime/autoconf time). For the longer term, a facility for filling in a pt_regs struct on demand would be nice to find and use.
first sketch in 30a77b
There are problems with the "first sketch". We can detect pt_regs-less operation, but currently don't compensate for it properly. Even if we could save registers spontaneously into the backup pt_regs in the context, the stap module may not have unwind data available to make full use of it. So let's try something a bit different. If the backtracing code in the runtime/tapset detects that it's being run without context->regs, let it try to use the kernel save_stack_trace() API. This can generate an array of PC values, which then our code could convert to a list of strings.
To test the show_stack() fallback, the following script could be a new test case: probe begin { print_backtrace() }
For the record, the kernel's per-arch kretprobe_trampoline_holder functions serve to create/fill in pt_regs from any old point.
Is there some thought on getting backtraces for tasks other than the one currently running might be obtained? A number of the tracepoints available provide a task_struct pointer: kernel.trace("activate_task") $p:struct task_struct* $rq:struct rq* kernel.trace("deactivate_task") $p:struct task_struct* $rq:struct rq* kernel.trace("sched_process_exit") $p:struct task_struct* kernel.trace("sched_process_fork") $parent:struct task_struct* $child:struct task_struct* kernel.trace("sched_process_free") $p:struct task_struct* kernel.trace("sched_switch") $rq:struct rq* $prev:struct task_struct* $next:struct task_struct* kernel.trace("sched_wakeup_new") $rq:struct rq* $p:struct task_struct* $success:int kernel.trace("sched_wakeup") $rq:struct rq* $p:struct task_struct* $success:int A "task_backtrace:string (task:long)" function would be useful for the latencytap.stp
It seems pretty hard to get reliable pt_regs from "thin air". The issue is that we need to unwind through our own runtime stap module. But currently we don't have unwind info for it at hand. So for now go with option number 2, use the kernel builtin dump_stack if available: commit 207d2da9298e751279039ddd8aac11fd6678e301 Author: Mark Wielaard <mjw@redhat.com> Date: Wed Aug 17 13:46:48 2011 +0200 PR6961 - backtrace from non-pt_regs probe context When printing a kernel backtrace use the kernel dump_trace if available. If the kernel is compiled with frame pointers we can guess the stack pionter pretty reliably, otherwise let dump_stack figure it out and skip some of the framework stack frames before starting the print the remaining stack. This seems to work in most cases for kernel.trace() probes (although not always). The code currently also tries to provide a kernel backtrace when the (timer) probe triggered in a user space context. This might not be too useful, since it isn't clear how the kernel backtrace really corresponds to the user space context, and most of the time dump_stack isn't actually smart enough to recreate the kernel stack (through the stap probe invocation).
Lets close this because commit 207d2d from comment #7 implements the original request of having backtraces from non-pt_regs probe context (if the kernel implements dump_trace). We can open a new bug report for wanting synthesized pt_regs if needed.