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 }
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_vlog (enum code type, const char *func, int line, const char *fmt, va_list args) { int num; char *buf = per_cpu_ptr(Stp_lbuf, get_cpu()); int start = 0; if (type == DBUG) { start = _stp_snprintf(buf, STP_LOG_BUF_LEN, "%s:%d: ", func, line); } else if (type == WARN) { /* This strcpy() is OK, since we know STP_LOG_BUF_LEN * is > sizeof(WARN_STRING). */ strcpy (buf, WARN_STRING); start = sizeof(WARN_STRING) - 1; } else if (type == ERROR) { /* This strcpy() is OK, since we know STP_LOG_BUF_LEN * is > sizeof(ERR_STRING) (which is < sizeof(WARN_STRING). */ strcpy (buf, ERR_STRING); start = sizeof(ERR_STRING) - 1; } num = vscnprintf (buf + start, STP_LOG_BUF_LEN - start - 1, fmt, args); if (num + start) { if (buf[num + start - 1] != '\n') { buf[num + start] = '\n'; num++; buf[num + start] = '\0'; } #ifdef STAP_DEBUG_PRINTK if (type == DBUG) printk (KERN_DEBUG "%s", buf); else if (type == WARN) printk (KERN_WARNING "%s", buf); else if (type == ERROR) printk (KERN_ERR "%s", buf); else printk (KERN_INFO "%s", buf); #else if (type != DBUG) { _stp_ctl_send(STP_OOB_DATA, buf, start + num + 1); } else { _stp_print(buf); _stp_print_flush(); } #endif } put_cpu(); }
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 }