From: Mark Wielaard Date: Tue, 20 Sep 2011 09:48:28 +0000 (+0200) Subject: Introduce _stp_get_uregs and _STP_PROBE_STATE_FULL_UREGS flag. X-Git-Tag: release-1.7~153^2~14 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=e13b5aba4d5fc678d58556b3e3faf74fea94eb47;p=systemtap.git Introduce _stp_get_uregs and _STP_PROBE_STATE_FULL_UREGS flag. No actual functionality change yet. _STP_PROBE_STATE_FULL_UREGS is set for context probe_flags if full user register set is available after calling _stp_get_uregs(). --- diff --git a/runtime/runtime_defines.h b/runtime/runtime_defines.h index 6a31d2fce..0fb29ba0f 100644 --- a/runtime/runtime_defines.h +++ b/runtime/runtime_defines.h @@ -99,3 +99,5 @@ typedef char string_t[MAXSTRINGLEN]; /* Defines for CONTEXT probe_flags. */ /* Probe occured in user space, also indicate regs fully from user. */ #define _STP_PROBE_STATE_USER_MODE 1 +/* _stp_get_uregs() was called and full user registers were recovered. */ +#define _STP_PROBE_STATE_FULL_UREGS 2 diff --git a/runtime/stack.c b/runtime/stack.c index 62836bebd..e52b4f4f4 100644 --- a/runtime/stack.c +++ b/runtime/stack.c @@ -145,6 +145,27 @@ static void _stp_stack_print_fallback(unsigned long s, int v, int l, int k) { // used through context-unwind.stp. #if defined (CONFIG_KPROBES) +/** Gets user space registers when available, also sets context probe_flags + * _STP_PROBE_STATE_FULL_UREGS if appropriate. Should be used instead of + * accessing context uregs field directly when (full) uregs are needed + * from kernel context. + */ +static struct pt_regs *_stp_get_uregs(struct context *c) +{ + /* When the probe occurred in user context uregs are always complete. */ + if (c->uregs && c->probe_flags & _STP_PROBE_STATE_USER_MODE) + c->probe_flags |= _STP_PROBE_STATE_FULL_UREGS; + else if (c->uregs == NULL) + { + /* First try simple recovery through task_pt_regs, + on some platforms that already provides complete uregs. */ + c->uregs = task_pt_regs (current); + if (_stp_task_pt_regs_valid(current, c->uregs)) + c->probe_flags |= _STP_PROBE_STATE_FULL_UREGS; + } + return c->uregs; +} + /** Prints the stack backtrace * @param regs A pointer to the struct pt_regs. * @param verbose _STP_SYM_FULL or _STP_SYM_BRIEF @@ -200,14 +221,8 @@ static void _stp_stack_print(struct context *c, int sym_flags, int stack_flags) in __stp_stack_print() below. */ } } else if (stack_flags == _STP_STACK_USER) { - /* use task_pt_regs, regs might be kernel regs, or not set. */ - if (c->uregs && (c->probe_flags & _STP_PROBE_STATE_USER_MODE)) { - regs = c->uregs; - uregs_valid = 1; - } else { - regs = task_pt_regs(current); - uregs_valid = _stp_task_pt_regs_valid(current, regs); - } + 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)