static void _stp_stack_user_print(struct context *c, int sym_flags) { struct pt_regs *regs = NULL; int uregs_valid = 0; struct uretprobe_instance *ri = NULL; if (c->probe_type == _STP_PROBE_HANDLER_URETPROBE) ri = c->ips.ri; #ifdef STAPCONF_UPROBE_GET_PC else if (c->probe_type == _STP_PROBE_HANDLER_UPROBE) ri = GET_PC_URETPROBE_NONE; #endif regs = _stp_get_uregs(c); uregs_valid = c->probe_flags & _STP_PROBE_STATE_FULL_UREGS; if (! current->mm || ! regs) { if (sym_flags & _STP_SYM_SYMBOL) _stp_printf("<no user backtrace at %s>\n", c->probe_point); else _stp_print("\n"); return; } /* print the current address */ #ifdef STAPCONF_UPROBE_GET_PC if (c->probe_type == _STP_PROBE_HANDLER_URETPROBE && ri) { if ((sym_flags & _STP_SYM_FULL) == _STP_SYM_FULL) { _stp_print("Returning from: "); /* ... otherwise this dereference fails */ _stp_print_addr(ri->rp->u.vaddr, sym_flags, current); _stp_print("Returning to : "); _stp_print_addr(ri->ret_addr, sym_flags, current); } else _stp_print_addr(ri->ret_addr, sym_flags, current); } else { _stp_print_addr(REG_IP(regs), sym_flags, current); } #else _stp_print_addr(REG_IP(regs), sym_flags, current); #endif /* 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_user_print(regs, sym_flags, MAXBACKTRACE, &c->uwcontext, ri, uregs_valid); #else /* User stack traces only supported for arches with dwarf unwinder. */ if (sym_flags & _STP_SYM_SYMBOL) _stp_printf("<no user backtrace support on arch>\n"); else _stp_print("\n"); #endif }
/** Write the registers to a string. * @param regs The pt_regs saved by the kprobe. * @note i386 and x86_64 only so far. */ static void _stp_print_regs(struct pt_regs * regs) { _stp_printf ("EIP: %08lx\n", EREG(ip, regs)); _stp_printf ("ESP: %08lx\n", EREG(sp, regs)); _stp_printf ("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", EREG(ax, regs), EREG(bx, regs), EREG(cx, regs), EREG(dx, regs)); _stp_printf ("ESI: %08lx EDI: %08lx EBP: %08lx\n", EREG(si, regs), EREG(di, regs), EREG(bp, regs)); }
static void _stp_stack_user_print(struct context *c, int sym_flags) { struct pt_regs *regs = NULL; struct uretprobe_instance *ri = NULL; unsigned n; unsigned long l; if (c->probe_type == stp_probe_type_uretprobe) ri = c->ips.ri; #ifdef STAPCONF_UPROBE_GET_PC else if (c->probe_type == stp_probe_type_uprobe) ri = GET_PC_URETPROBE_NONE; #endif regs = _stp_get_uregs(c); if (! current->mm || ! regs) { if (sym_flags & _STP_SYM_SYMBOL) _stp_printf("<no user backtrace at %s>\n", c->probe_point); else _stp_print("\n"); return; } /* print the current address */ #ifdef STAPCONF_UPROBE_GET_PC if (c->probe_type == stp_probe_type_uretprobe && ri) { if ((sym_flags & _STP_SYM_FULL) == _STP_SYM_FULL) { _stp_print("Returning from: "); /* ... otherwise this dereference fails */ _stp_print_addr(ri->rp->u.vaddr, sym_flags, current); _stp_print("Returning to : "); } } #endif _stp_print_addr(_stp_stack_user_get(c, 0), sym_flags, current); /* print rest of stack... */ #ifdef STP_USE_DWARF_UNWINDER for (n = 1; n < MAXBACKTRACE; n++) { l = _stp_stack_user_get(c, n); if (l == 0) break; // No user space fallback available _stp_print_addr(l, sym_flags, current); } #else /* User stack traces only supported for arches with dwarf unwinder. */ if (sym_flags & _STP_SYM_SYMBOL) _stp_printf("<no user backtrace support on arch>\n"); else _stp_print("\n"); #endif }
static void _stp_print_regs(struct pt_regs * regs) { int i; _stp_printf("NIP: %016lX", regs->nip); for (i = 0; i < 32; i++) { if ((i % 4) == 0) { _stp_printf("\n GPR%02d: ", i); } _stp_printf("%016lX ", regs->gpr[i]); } _stp_printf("\n"); }
static void _stp_print_regs(struct pt_regs * regs) { _stp_printf("RIP: %016lx\nRSP: %016lx\n", RREG(ip, regs), RREG(sp, regs)); _stp_printf("RAX: %016lx RBX: %016lx RCX: %016lx\n", RREG(ax, regs), RREG(bx, regs), RREG(cx, regs)); _stp_printf("RDX: %016lx RSI: %016lx RDI: %016lx\n", RREG(dx, regs), RREG(si, regs), RREG(di, regs)); _stp_printf("RBP: %016lx R08: %016lx R09: %016lx\n", RREG(bp, regs), regs->r8, regs->r9); _stp_printf("R10: %016lx R11: %016lx R12: %016lx\n", regs->r10, regs->r11, regs->r12); _stp_printf("R13: %016lx R14: %016lx R15: %016lx\n", regs->r13, regs->r14, regs->r15); }
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 }