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
}
Beispiel #2
0
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
}