From 771602ec006efbb21a611a64593fdb64547ab474 Mon Sep 17 00:00:00 2001 From: Tao Liu Date: Mon, 29 Jul 2024 22:44:29 +1200 Subject: [PATCH] Stop stack unwinding at non-kernel address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 #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 Cc: Sourabh Jain Cc: Hari Bathini Cc: Mahesh J Salgaonkar Cc: Naveen N. Rao Cc: Lianbo Jiang Cc: HAGIO KAZUHITO(萩尾 一仁) Cc: Tao Liu Cc: Alexey Makhalov Signed-off-by: Tao Liu --- 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 82c2af80..f18d7818 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 0bed96a3..2a52a8b0 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 7399fd0a..2965a100 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. */