diff options
author | Vasily Gorbik <gor@linux.ibm.com> | 2019-11-22 18:52:40 +0100 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2019-11-30 10:52:48 +0100 |
commit | 0610154650f161d56a0bef0d9678ae1de7360019 (patch) | |
tree | 79b1b8933d8bc5ac07c50c2961afb0a17a82a05e | |
parent | 7868249fbbc8125b82b83d99d33b23897ae7d9ab (diff) |
s390/test_unwind: print verbose unwinding results
Add stack name, sp and reliable information into test unwinding
results. Also consider ip outside of kernel text as failure if the
state is reported reliable.
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
-rw-r--r-- | arch/s390/kernel/dumpstack.c | 1 | ||||
-rw-r--r-- | arch/s390/lib/test_unwind.c | 12 |
2 files changed, 11 insertions, 2 deletions
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index fc442aec0d96..d74e21a23703 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -38,6 +38,7 @@ const char *stack_type_name(enum stack_type type) return "unknown"; } } +EXPORT_SYMBOL_GPL(stack_type_name); static inline bool in_stack(unsigned long sp, struct stack_info *info, enum stack_type type, unsigned long low, diff --git a/arch/s390/lib/test_unwind.c b/arch/s390/lib/test_unwind.c index 687a6922beda..db94e657c056 100644 --- a/arch/s390/lib/test_unwind.c +++ b/arch/s390/lib/test_unwind.c @@ -56,11 +56,19 @@ static noinline int test_unwind(struct task_struct *task, struct pt_regs *regs, unsigned long addr = unwind_get_return_address(&state); char sym[KSYM_SYMBOL_LEN]; - if (!addr || frame_count == max_frames) + if (frame_count++ == max_frames) break; + if (state.reliable && !addr) { + pr_err("unwind state reliable but addr is 0\n"); + return -EINVAL; + } sprint_symbol(sym, addr); if (bt_pos < BT_BUF_SIZE) { - bt_pos += snprintf(bt + bt_pos, BT_BUF_SIZE - bt_pos, "%s\n", sym); + bt_pos += snprintf(bt + bt_pos, BT_BUF_SIZE - bt_pos, + state.reliable ? " [%-7s%px] %pSR\n" : + "([%-7s%px] %pSR)\n", + stack_type_name(state.stack_info.type), + (void *)state.sp, (void *)state.ip); if (bt_pos >= BT_BUF_SIZE) pr_err("backtrace buffer is too small\n"); } |