The stack unwinding is for kernel addresses only. If non-kernel address
encountered, it is usually a user space address, or non-address value
like a function call parameter. So stopping stack unwinding at non-kernel
address will decrease the invalid unwind results.
Before:
crash> gdb bt
#0 0xffffffff816a8f65 in context_switch ...
#1 __schedule () ...
#2 0xffffffff816a94e9 in schedule ...
#3 0xffffffff816a86fd in schedule_hrtimeout_range_clock ...
#4 0xffffffff816a8733 in schedule_hrtimeout_range ...
#5 0xffffffff8124bb7e in ep_poll ...
#6 0xffffffff8124d00d in SYSC_epoll_wait ...
#7 SyS_epoll_wait ...
#8 <signal handler called>
#9 0x00007f0449407923 in ?? ()
#10 0xffff880100000001 in ?? ()
#11 0xffff880169b3c010 in ?? ()
#12 0x0000000000000040 in irq_stack_union ()
#13 0xffff880169b3c058 in ?? ()
#14 0xffff880169b3c048 in ?? ()
#15 0xffff880169b3c050 in ?? ()
#16 0x0000000000000000 in ?? ()
After:
crash> gdb bt
#0 0xffffffff816a8f65 in context_switch ...
#1 __schedule () ...
#2 0xffffffff816a94e9 in schedule () ...
#3 0xffffffff816a86fd in schedule_hrtimeout_range_clock ...
#4 0xffffffff816a8733 in schedule_hrtimeout_range ...
#5 0xffffffff8124bb7e in ep_poll ...
#6 0xffffffff8124d00d in SYSC_epoll_wait ...
#7 SyS_epoll_wait ...
#8 <signal handler called>
Cc: Sourabh Jain <sourabhjain(a)linux.ibm.com>
Cc: Hari Bathini <hbathini(a)linux.ibm.com>
Cc: Mahesh J Salgaonkar <mahesh(a)linux.ibm.com>
Cc: Naveen N. Rao <naveen.n.rao(a)linux.vnet.ibm.com>
Cc: Lianbo Jiang <lijiang(a)redhat.com>
Cc: HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab(a)nec.com>
Cc: Tao Liu <ltao(a)redhat.com>
Cc: Alexey Makhalov <alexey.makhalov(a)broadcom.com>
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
defs.h | 1 +
gdb-10.2.patch | 26 ++++++++++++++++++++++++++
gdb_interface.c | 6 ++++++
3 files changed, 33 insertions(+)
diff --git a/defs.h b/defs.h
index 82c2af8..f18d781 100644
--- a/defs.h
+++ b/defs.h
@@ -7906,6 +7906,7 @@ extern unsigned char *gdb_prettyprint_arrays;
extern unsigned int *gdb_repeat_count_threshold;
extern unsigned char *gdb_stop_print_at_null;
extern unsigned int *gdb_output_radix;
+int is_kvaddr(ulong);
/*
* gdb/top.c
diff --git a/gdb-10.2.patch b/gdb-10.2.patch
index 0bed96a..2a52a8b 100644
--- a/gdb-10.2.patch
+++ b/gdb-10.2.patch
@@ -16171,3 +16171,29 @@ exit 0
}
/*
+--- gdb-10.2/gdb/stack.c.orig
++++ gdb-10.2/gdb/stack.c
+@@ -1990,6 +1990,10 @@
+ /* Print briefly all stack frames or just the innermost COUNT_EXP
+ frames. */
+
++#ifdef CRASH_MERGE
++extern "C" int is_kvaddr(ulong);
++#endif
++
+ static void
+ backtrace_command_1 (const frame_print_options &fp_opts,
+ const backtrace_cmd_options &bt_opts,
+@@ -2082,6 +2086,12 @@
+ hand, perhaps the code does or could be fixed to make sure
+ the frame->prev field gets set to NULL in that case). */
+
++ CORE_ADDR pc = 0;
++ get_frame_pc_if_available (fi, &pc);
++ if (!is_kvaddr(pc)) {
++ fi = NULL;
++ break;
++ }
+ print_frame_info (fp_opts, fi, 1, LOCATION, 1, 0);
+ if ((flags & PRINT_LOCALS) != 0)
+ {
diff --git a/gdb_interface.c b/gdb_interface.c
index 7399fd0..2965a10 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -947,6 +947,12 @@ gdb_lookup_module_symbol(ulong addr, ulong *offset)
}
}
+int
+is_kvaddr(ulong addr)
+{
+ return IS_KVADDR(addr);
+}
+
/*
* Used by gdb_interface() to catch gdb-related errors, if desired.
*/
--
2.40.1