s390/test_unwind: print verbose unwinding results
authorVasily Gorbik <gor@linux.ibm.com>
Fri, 22 Nov 2019 17:52:40 +0000 (18:52 +0100)
committerVasily Gorbik <gor@linux.ibm.com>
Sat, 30 Nov 2019 09:52:48 +0000 (10:52 +0100)
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>
arch/s390/kernel/dumpstack.c
arch/s390/lib/test_unwind.c

index fc442aec0d9633dc3228ecc6f2fd218696134b37..d74e21a23703ed77f5e7bd5f6da438189de335fd 100644 (file)
@@ -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,
index 687a6922bedaa041b0961fc30650d764a2e549b4..db94e657c056dd6d974c16c6f29026b4d80635d6 100644 (file)
@@ -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");
                }