static void _stp_stack_kernel_print(struct context *c, int sym_flags) { unsigned n, remaining; unsigned long l; /* print the current address */ if (c->probe_type == stp_probe_type_kretprobe && c->ips.krp.pi && (sym_flags & _STP_SYM_FULL) == _STP_SYM_FULL) { _stp_print("Returning from: "); _stp_print_addr((unsigned long)_stp_probe_addr_r(c->ips.krp.pi), sym_flags, NULL); _stp_print("Returning to : "); } _stp_print_addr(_stp_stack_kernel_get(c, 0), sym_flags, NULL); #ifdef STP_USE_DWARF_UNWINDER for (n = 1; n < MAXBACKTRACE; n++) { l = _stp_stack_kernel_get(c, n); if (l == 0) { remaining = MAXBACKTRACE - n; _stp_stack_print_fallback(UNW_SP(&c->uwcontext_kernel.info), sym_flags, remaining, 0); break; } else { _stp_print_addr(l, sym_flags, NULL); } } #else if (! c->kregs) { /* This is a fatal block for _stp_stack_kernel_get, * but when printing a backtrace we can use this * inexact fallback. * * When compiled with frame pointers we can do * a pretty good guess at the stack value, * otherwise let dump_stack guess it * (and skip some framework frames). */ #if defined(STAPCONF_KERNEL_STACKTRACE) || defined(STAPCONF_KERNEL_STACKTRACE_NO_BP) unsigned long sp; int skip; #ifdef CONFIG_FRAME_POINTER sp = *(unsigned long *) __builtin_frame_address (0); skip = 1; /* Skip just this frame. */ #else sp = 0; skip = 5; /* yes, that many framework frames. */ #endif _stp_stack_print_fallback(sp, sym_flags, MAXBACKTRACE, skip); #else if (sym_flags & _STP_SYM_SYMBOL) _stp_printf("<no kernel backtrace at %s>\n", c->probe_point); else _stp_print("\n"); #endif return; } else /* Arch specific fallback for kernel backtraces. */ __stp_stack_print(c->kregs, sym_flags, MAXBACKTRACE); #endif }
static void _stp_stack_kernel_print(struct context *c, int sym_flags) { struct pt_regs *regs = NULL; if (! c->kregs) { /* For the kernel we can use an inexact fallback. When compiled with frame pointers we can do a pretty good guess at the stack value, otherwise let dump_stack guess it (and skip some framework frames). */ #if defined(STAPCONF_KERNEL_STACKTRACE) || defined(STAPCONF_KERNEL_STACKTRACE_NO_BP) unsigned long sp; int skip; #ifdef CONFIG_FRAME_POINTER sp = *(unsigned long *) __builtin_frame_address (0); skip = 1; /* Skip just this frame. */ #else sp = 0; skip = 5; /* yes, that many framework frames. */ #endif _stp_stack_print_fallback(sp, sym_flags, MAXBACKTRACE, skip); #else if (sym_flags & _STP_SYM_SYMBOL) _stp_printf("<no kernel backtrace at %s>\n", c->probe_point); else _stp_print("\n"); #endif return; } else { regs = c->kregs; } /* print the current address */ if (c->probe_type == _STP_PROBE_HANDLER_KRETPROBE && c->ips.krp.pi) { if ((sym_flags & _STP_SYM_FULL) == _STP_SYM_FULL) { _stp_print("Returning from: "); _stp_print_addr((unsigned long)_stp_probe_addr_r(c->ips.krp.pi), sym_flags, NULL); _stp_print("Returning to : "); } _stp_print_addr((unsigned long)_stp_ret_addr_r(c->ips.krp.pi), sym_flags, NULL); } else { _stp_print_addr(REG_IP(regs), sym_flags, NULL); } /* print rest of stack... */ #ifdef STP_USE_DWARF_UNWINDER if (c->uregs == &c->uwcontext.info.regs) { /* Unwinder needs the reg state, clear uregs ref. */ c->uregs = NULL; c->probe_flags &= ~_STP_PROBE_STATE_FULL_UREGS; } __stp_dwarf_stack_kernel_print(regs, sym_flags, MAXBACKTRACE, &c->uwcontext); #else /* Arch specific fallback for kernel backtraces. */ __stp_stack_print(regs, sym_flags, MAXBACKTRACE); #endif }