[PATCH v4 00/16] gdb stack unwinding support for crash utility
by Tao Liu
This patchset is a rebase/merged version of the following 3 patchsets:
1): [PATCH v10 0/5] Improve stack unwind on ppc64 [1]
2): [PATCH 0/5] x86_64 gdb stack unwinding support [2]
3): Clean up on top of one-thread-v2 [3]
A complete description of gdb stack unwinding support for crash can be
found in [1].
This patchset can be divided into the following 2 parts:
1) part1: arch independent, mainly modify on the
crash_target.c/gdb_interface.c files, in preparation of the
gdb side.
2) part2: arch specific part, for implementing ppc64/x86_64/arm64/vmware
gdb stack unwinding support.
=== part 2
- arm64:
arm64: Add gdb stack unwinding support
- vmware:
vmware_guestdump: Various format versions support
x86_64: fix gdb bt for vmware dumps
set_context(): check if context is already current
- x86_64:
x86_64: Fix invalid input "=>" for bt command
Fix cpumask_t recursive dependence issue
Parse stack by inactive_stack_frame priorily if the struct is valid
x86_64: Add gdb stack unwinding support
- ppc64:
ppc64: correct gdb passthroughs by implementing machdep->get_cpu_reg
=== part 1
Stop stack unwinding at non-kernel address
Fix gdb_interface: restore gdb's output streams at end of gdb_interface
Print task pid/command instead of CPU index
Rename get_cpu_reg to get_current_task_reg
Let crash change gdb context
Leave only one gdb thread for crash
Remove 'frame' from prohibited commands list
===
v4 -> v3:
Fixed the author issue in [PATCH v3 06/16] Fix gdb_interface: restore gdb's
output streams at end of gdb_interface.
v3 -> v2:
1) Updated CC list as pointed out in [4]
2) Compiling issues as in [5]
v2 -> v1:
1) Added the patch: x86_64: Fix invalid input "=>" for bt command,
thanks for Kazu's testing.
2) Modify the patch: x86_64: Add gdb stack unwinding support, added the
pcp_save, spp_save and sp, for restoring the value in match of the original
code logic.
[1]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00469.html
[2]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00488.html
[3]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00554.html
[4]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00681.html
[5]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00715.html
Aditya Gupta (2):
Remove 'frame' from prohibited commands list
ppc64: correct gdb passthroughs by implementing machdep->get_cpu_reg
Alexey Makhalov (3):
set_context(): check if context is already current
x86_64: fix gdb bt for vmware dumps
vmware_guestdump: Various format versions support
Tao Liu (11):
Leave only one gdb thread for crash
Let crash change gdb context
Rename get_cpu_reg to get_current_task_reg
Print task pid/command instead of CPU index
Fix gdb_interface: restore gdb's output streams at end of
gdb_interface
Stop stack unwinding at non-kernel address
x86_64: Add gdb stack unwinding support
Parse stack by inactive_stack_frame priorily if the struct is valid
Fix cpumask_t recursive dependence issue
x86_64: Fix invalid input "=>" for bt command
arm64: Add gdb stack unwinding support
arm64.c | 114 +++++++++++++++-
crash_target.c | 47 ++++---
defs.h | 187 ++++++++++++++++++++++++++-
gdb-10.2.patch | 79 ++++++++++++
gdb_interface.c | 33 ++---
kernel.c | 61 +++++++--
ppc64.c | 163 ++++++++++++++++++++++-
task.c | 33 +++--
tools.c | 8 +-
vmware_guestdump.c | 316 ++++++++++++++++++++++++++++++++-------------
x86_64.c | 302 ++++++++++++++++++++++++++++++++++++++-----
11 files changed, 1151 insertions(+), 192 deletions(-)
--
2.40.1
3 months, 3 weeks
[Crash-Utility][PATCH v2 00/13] gdb stack unwinding support for crash utility
by Tao Liu
This patchset is a rebase/merged version of the following 3 patchsets:
1): [PATCH v10 0/5] Improve stack unwind on ppc64 [1]
2): [PATCH 0/5] x86_64 gdb stack unwinding support [2]
3): Clean up on top of one-thread-v2 [3]
A complete description of gdb stack unwinding support for crash can be
found in [1].
This patchset can be divided into the following 2 parts:
1) part1: arch independent, mainly modify on the
crash_target.c/gdb_interface.c files, in preparation of the
gdb side.
2) part2: arch specific part, for implementing ppc64/x86_64/arm64 gdb
stack unwinding support.
=== part 2
arm64: Add gdb stack unwinding support
Fix cpumask_t recursive dependence issue
Parse stack by inactive_stack_frame priorily if the struct is valid
x86_64: Add gdb stack unwinding support
ppc64: correct gdb passthroughs by implementing machdep->get_cpu_reg
=== part 1
Stop stack unwinding at non-kernel address
Fix gdb_interface: restore gdb's output streams at end of gdb_interface
Print task pid/command instead of CPU index
Rename get_cpu_reg to get_current_task_reg
Let crash change gdb context
Leave only one gdb thread for crash
Remove 'frame' from prohibited commands list
===
v2 -> v1:
1) Added the patch: x86_64: Fix invalid input "=>" for bt command,
thanks for Kazu's testing.
2) Modify the patch: x86_64: Add gdb stack unwinding support, added the
pcp_save, spp_save and sp, for restoring the value in match of the original
code logic.
[1]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00469.html
[2]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00488.html
[3]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00554.html
Aditya Gupta (2):
Remove 'frame' from prohibited commands list
ppc64: correct gdb passthroughs by implementing machdep->get_cpu_reg
Tao Liu (11):
Leave only one gdb thread for crash
Let crash change gdb context
Rename get_cpu_reg to get_current_task_reg
Print task pid/command instead of CPU index
Fix gdb_interface: restore gdb's output streams at end of
gdb_interface
Stop stack unwinding at non-kernel address
x86_64: Add gdb stack unwinding support
Parse stack by inactive_stack_frame priorily if the struct is valid
Fix cpumask_t recursive dependence issue
x86_64: Fix invalid input "=>" for bt command
arm64: Add gdb stack unwinding support
arm64.c | 114 +++++++++++++++++-
crash_target.c | 47 +++++---
defs.h | 187 +++++++++++++++++++++++++++++-
gdb-10.2.patch | 79 +++++++++++++
gdb_interface.c | 33 ++----
kernel.c | 61 ++++++++--
ppc64.c | 163 ++++++++++++++++++++++++--
task.c | 30 +++--
tools.c | 8 +-
x86_64.c | 299 +++++++++++++++++++++++++++++++++++++++++++-----
10 files changed, 916 insertions(+), 105 deletions(-)
--
2.40.1
4 months, 1 week
Re: [PATCH] x86_64: Add top_of_kernel_stack_padding for kernel stack
by Lianbo Jiang
Hi, Tao
Thank you for the fix.
On 5/23/24 12:06 PM, devel-request(a)lists.crash-utility.osci.io wrote:
> Date: Thu, 23 May 2024 12:06:03 +0800
> From: Tao Liu<ltao(a)redhat.com>
> Subject: [Crash-utility] [PATCH] x86_64: Add
> top_of_kernel_stack_padding for kernel stack
> To:devel@lists.crash-utility.osci.io
> Cc: Tao Liu<ltao(a)redhat.com>
> Message-ID:<20240523040603.10304-1-ltao(a)redhat.com>
> Content-Type: text/plain; charset="US-ASCII"; x-default=true
>
> With kernel patch [1], x86_64 will add extra padding for kernel stack,
> as a result, the pt_regs will be shift down by the offset of padding.
> Without the patch, the values of registers read from pt_regs will be
> incorrect.
>
> Though currently the TOP_OF_KERNEL_STACK_PADDING is configured by
> Kconfig, according to kernel code comment [2], the value may be made
> dynamicly later. In addition there might be systems compiled without
> Kconfig avaliable. So in this patch, we will calculate the value of
> TOP_OF_KERNEL_STACK_PADDING.
>
> The calculation is as follows:
>
> 1) in startup_64(), there is a lea instruction as:
> leaq (__end_init_task - TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE)(%rip), %rsp
>
> 2) in rewind_stack_and_make_dead(), there is a lea instruction as:
> leaq -PTREGS_SIZE(%rax), %rsp
>
> The disassembled 2 instructions will be like:
>
> 1) 0xffffffff93a0007d <startup_64+3>: lea 0x1e03ec4(%rip),%rsp # 0xffffffff95803f48
> ^^^^^^^^^^^^^^^^^^^^
> 2) 0xffffffff93a0465a <rewind_stack_and_make_dead+10>: lea -0xa8(%rax),%rsp
> ^^^^
> 0xffffffff95803f48 is the value of (__end_init_task -
> TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE), and 0xa8 is the value of
> PTREGS_SIZE, __end_init_task can be get by symbol reading.
Calculating the value of TOP_OF_KERNEL_STACK_PADDING, which looks good, but it heavily relies on compiler.
Normally we would use this way unless there is no other choice.
How about the following changes? Although it doesn't handle the case that the value is dynamic, let's see
how to change in the kernel in future, and then consider how to reflect it in crash-utility.
diff --git a/defs.h b/defs.h
index 01f316e67dde..42d875965256 100644
--- a/defs.h
+++ b/defs.h
@@ -2414,6 +2414,7 @@ struct size_table { /* stash of commonly-used sizes */
long maple_tree;
long maple_node;
long module_memory;
+ long fred_frame;
};
struct array_table {
diff --git a/kernel.c b/kernel.c
index 1728b70c1b5c..cd3d6044cc9a 100644
--- a/kernel.c
+++ b/kernel.c
@@ -668,6 +668,7 @@ kernel_init()
STRUCT_SIZE_INIT(softirq_state, "softirq_state");
STRUCT_SIZE_INIT(softirq_action, "softirq_action");
STRUCT_SIZE_INIT(desc_struct, "desc_struct");
+ STRUCT_SIZE_INIT(fred_frame, "fred_frame");
STRUCT_SIZE_INIT(char_device_struct, "char_device_struct");
if (VALID_STRUCT(char_device_struct)) {
diff --git a/x86_64.c b/x86_64.c
index 0c21eb827e4a..6777c93e6b47 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -4086,10 +4086,11 @@ in_exception_stack:
if (!irq_eframe && !is_kernel_thread(bt->tc->task) &&
(GET_STACKBASE(bt->tc->task) == bt->stackbase)) {
+ long stack_padding_size = SIZE(fred_frame) > 0 ? (2*8) : 0;
user_mode_eframe = bt->stacktop - SIZE(pt_regs);
if (last_process_stack_eframe < user_mode_eframe)
x86_64_exception_frame(EFRAME_PRINT, 0, bt->stackbuf +
- (bt->stacktop - bt->stackbase) - SIZE(pt_regs),
+ (bt->stacktop - stack_padding_size - bt->stackbase) - SIZE(pt_regs),
bt, ofp);
}
@@ -4407,10 +4408,11 @@ in_exception_stack:
if (!irq_eframe && !is_kernel_thread(bt->tc->task) &&
(GET_STACKBASE(bt->tc->task) == bt->stackbase)) {
+ long stack_padding_size = SIZE(fred_frame) > 0 ? (2*8) : 0;
user_mode_eframe = bt->stacktop - SIZE(pt_regs);
if (last_process_stack_eframe < user_mode_eframe)
x86_64_exception_frame(EFRAME_PRINT, 0, bt->stackbuf +
- (bt->stacktop - bt->stackbase) - SIZE(pt_regs),
+ (bt->stacktop - stack_padding_size - bt->stackbase) - SIZE(pt_regs),
bt, ofp);
}
Thanks
Lianbo
> [1]:https://lore.kernel.org/all/170668568261.398.10403890006820046961.tip-...
> [2]:https://elixir.bootlin.com/linux/v6.9.1/source/arch/x86/include/asm/th...
>
> Signed-off-by: Tao Liu<ltao(a)redhat.com>
> ---
> x86_64.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 82 insertions(+), 2 deletions(-)
>
> diff --git a/x86_64.c b/x86_64.c
> index 0c21eb8..43a31c2 100644
> --- a/x86_64.c
> +++ b/x86_64.c
> @@ -137,6 +137,7 @@ static orc_entry *orc_find(ulong);
> static orc_entry *orc_module_find(ulong);
> static ulong ip_table_to_vaddr(ulong);
> static void orc_dump(ulong);
> +static long top_of_kernel_stack_padding(void);
>
> struct machine_specific x86_64_machine_specific = { 0 };
>
> @@ -4089,7 +4090,8 @@ in_exception_stack:
> user_mode_eframe = bt->stacktop - SIZE(pt_regs);
> if (last_process_stack_eframe < user_mode_eframe)
> x86_64_exception_frame(EFRAME_PRINT, 0, bt->stackbuf +
> - (bt->stacktop - bt->stackbase) - SIZE(pt_regs),
> + (bt->stacktop - bt->stackbase) - SIZE(pt_regs) -
> + top_of_kernel_stack_padding(),
> bt, ofp);
> }
>
> @@ -4410,7 +4412,8 @@ in_exception_stack:
> user_mode_eframe = bt->stacktop - SIZE(pt_regs);
> if (last_process_stack_eframe < user_mode_eframe)
> x86_64_exception_frame(EFRAME_PRINT, 0, bt->stackbuf +
> - (bt->stacktop - bt->stackbase) - SIZE(pt_regs),
> + (bt->stacktop - bt->stackbase) - SIZE(pt_regs) -
> + top_of_kernel_stack_padding(),
> bt, ofp);
> }
>
> @@ -9541,4 +9544,81 @@ x86_64_swp_offset(ulong entry)
> return SWP_OFFSET(entry);
> }
>
> +static long
> +top_of_kernel_stack_padding(void)
> +{
> + char buf1[BUFSIZE];
> + char *cursor;
> + long final_value, ptregs_size_value;
> + char *arglist[MAXARGS];
> + bool found = FALSE;
> +
> + static long kernel_stack_padding = -1;
> +
> + if (kernel_stack_padding >= 0)
> + return kernel_stack_padding;
> +
> + /*
> + * startup_64:
> + * ...
> + * mov %rsi,%r15
> + * leaq (__end_init_task - TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE)(%rip), %rsp
> + */
> + sprintf(buf1, "disass /r startup_64");
> + open_tmpfile2();
> + if (!gdb_pass_through(buf1, pc->tmpfile2, GNU_RETURN_ON_ERROR)) {
> + kernel_stack_padding = 0;
> + goto out;
> + }
> +
> + rewind(pc->tmpfile2);
> + while (fgets(buf1, BUFSIZE, pc->tmpfile2) && !found) {
> + // machine code of "mov %rsi,%r15"
> + if (strstr(buf1, "49 89 f7"))
> + found = TRUE;
> + }
> + if (!found || !(cursor = strstr(buf1, "# 0x"))) {
> + kernel_stack_padding = 0;
> + goto out;
> + }
> +
> + parse_line(cursor, arglist);
> + final_value = stol(arglist[1], FAULT_ON_ERROR, NULL);
> +
> + /*
> + * rewind_stack_and_make_dead:
> + * ...
> + * leaq -PTREGS_SIZE(%rax), %rsp
> + */
> + found = FALSE;
> + rewind(pc->tmpfile2);
> + sprintf(buf1, "disass rewind_stack_and_make_dead");
> + if (!gdb_pass_through(buf1, pc->tmpfile2, GNU_RETURN_ON_ERROR)) {
> + kernel_stack_padding = 0;
> + goto out;
> + }
> + rewind(pc->tmpfile2);
> + while (fgets(buf1, BUFSIZE, pc->tmpfile2)) {
> + // find leaq -PTREGS_SIZE(%rax), %rsp
> + if (strstr(buf1, "lea") && (cursor = strstr(buf1, "-0x"))) {
> + parse_line(cursor, arglist);
> + char *p = strchr(arglist[0], '(');
> + *p = '\0';
> + ptregs_size_value = stol(arglist[0] + 1, FAULT_ON_ERROR, NULL);
> + found = TRUE;
> + break;
> + }
> + }
> + if (!found) {
> + kernel_stack_padding = 0;
> + goto out;
> + }
> +
> + struct syment *s = symbol_search("__end_init_task");
> + kernel_stack_padding = s->value - final_value - ptregs_size_value;
> +out:
> + close_tmpfile2();
> + return kernel_stack_padding;
> +}
> +
> #endif /* X86_64 */
> -- 2.40.1
4 months, 1 week
[PATCH v3 00/16] gdb stack unwinding support for crash utility
by Tao Liu
This patchset is a rebase/merged version of the following 3 patchsets:
1): [PATCH v10 0/5] Improve stack unwind on ppc64 [1]
2): [PATCH 0/5] x86_64 gdb stack unwinding support [2]
3): Clean up on top of one-thread-v2 [3]
A complete description of gdb stack unwinding support for crash can be
found in [1].
This patchset can be divided into the following 2 parts:
1) part1: arch independent, mainly modify on the
crash_target.c/gdb_interface.c files, in preparation of the
gdb side.
2) part2: arch specific part, for implementing ppc64/x86_64/arm64/vmware
gdb stack unwinding support.
=== part 2
- arm64:
arm64: Add gdb stack unwinding support
- vmware:
vmware_guestdump: Various format versions support
x86_64: fix gdb bt for vmware dumps
set_context(): check if context is already current
- x86_64:
x86_64: Fix invalid input "=>" for bt command
Fix cpumask_t recursive dependence issue
Parse stack by inactive_stack_frame priorily if the struct is valid
x86_64: Add gdb stack unwinding support
- ppc64:
ppc64: correct gdb passthroughs by implementing machdep->get_cpu_reg
=== part 1
Stop stack unwinding at non-kernel address
Fix gdb_interface: restore gdb's output streams at end of gdb_interface
Print task pid/command instead of CPU index
Rename get_cpu_reg to get_current_task_reg
Let crash change gdb context
Leave only one gdb thread for crash
Remove 'frame' from prohibited commands list
===
v3 -> v2:
1) Updated CC list as pointed out in [4]
2) Compiling issues as in [5]
v2 -> v1:
1) Added the patch: x86_64: Fix invalid input "=>" for bt command,
thanks for Kazu's testing.
2) Modify the patch: x86_64: Add gdb stack unwinding support, added the
pcp_save, spp_save and sp, for restoring the value in match of the original
code logic.
[1]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00469.html
[2]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00488.html
[3]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00554.html
[4]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00681.html
[5]: https://www.mail-archive.com/devel@lists.crash-utility.osci.io/msg00715.html
Aditya Gupta (2):
Remove 'frame' from prohibited commands list
ppc64: correct gdb passthroughs by implementing machdep->get_cpu_reg
Alexey Makhalov (3):
set_context(): check if context is already current
x86_64: fix gdb bt for vmware dumps
vmware_guestdump: Various format versions support
Tao Liu (11):
Leave only one gdb thread for crash
Let crash change gdb context
Rename get_cpu_reg to get_current_task_reg
Print task pid/command instead of CPU index
Fix gdb_interface: restore gdb's output streams at end of
gdb_interface
Stop stack unwinding at non-kernel address
x86_64: Add gdb stack unwinding support
Parse stack by inactive_stack_frame priorily if the struct is valid
Fix cpumask_t recursive dependence issue
x86_64: Fix invalid input "=>" for bt command
arm64: Add gdb stack unwinding support
arm64.c | 114 +++++++++++++++-
crash_target.c | 47 ++++---
defs.h | 187 ++++++++++++++++++++++++++-
gdb-10.2.patch | 79 ++++++++++++
gdb_interface.c | 33 ++---
kernel.c | 61 +++++++--
ppc64.c | 163 ++++++++++++++++++++++-
task.c | 33 +++--
tools.c | 8 +-
vmware_guestdump.c | 316 ++++++++++++++++++++++++++++++++-------------
x86_64.c | 302 ++++++++++++++++++++++++++++++++++++++-----
11 files changed, 1151 insertions(+), 192 deletions(-)
--
2.40.1
4 months, 1 week
crash8.0.5 cannot parse vmlinux compiled by google-A15-kernel6.6
by tianming.wang@unisoc.com
The crash tool cannot recognize this vmlinux.
The following error is reported.
gdb /home/tianming.wang/2656996/vmlinux
GNU gdb (GDB) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=aarch64-elf-linux".
Type "show configuration" for configuration details.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
BFD: /home/tianming.wang/2656996/vmlinux: unable to initialize decompress status for section .debug_aranges
"0x7ffd0dd35e10s": not in executable format: file format not recognized
crash_arm64_sprd_v8.0.5++.bin: /home/tianming.wang/2656996/vmlinux: no debugging data available
Please help to check it.
Thanks a lot~~
4 months, 1 week
Re: crash8.0.5 cannot parse vmlinux compiled by google-A15-kernel6.6
by lijiang
On Thu, May 23, 2024 at 12:07 PM <devel-request(a)lists.crash-utility.osci.io>
wrote:
> Date: Thu, 23 May 2024 01:28:12 -0000
> From: jarvis0922(a)gmail.com
> Subject: [Crash-utility] Re: crash8.0.5 cannot parse vmlinux compiled
> by google-A15-kernel6.6
> To: devel(a)lists.crash-utility.osci.io
> Message-ID: <20240523012812.12611.42286(a)lists.crash-utility.osci.io>
> Content-Type: text/plain; charset="utf-8"
>
> > On Wed, May 22, 2024 at 3:26 PM <jarvis0922(a)gmail.com> wrote:
> >
> > Hmm... Interesting. Frankly we don't have very strong motivation to
> > move to a higher version of gdb for now. But I guess your case will
> > increase the motivation. Have you tried
> > https://github.com/liutgnu/crash-preview, which is integrated with a
> > newer gdb. Does that work for you?
>
> It can work for me with vmlinux with CONFIG_DEBUG_INFO_COMPRESSED_ZSTD set
> Hope it could be good motivation to upgrade gdb as it seems to be more
> common to have it set
>
>
Thanks for pointing out this issue. Can you help to check if it can work
well for you as below? Just want to confirm if crash also works well
without the latest embedded gdb.
1. objcopy --decompress-debug-sections vmlinux
2. crash vmlinux vmcore
If yes, at least it can parse the current vmlinux(with compressed debug
info) until the new gdb grade is completed.
Thanks
Lianbo
Thanks.
>
>
> >
> > Thanks,
> > Tao Liu
>
4 months, 2 weeks
[PATCH] x86_64: Add top_of_kernel_stack_padding for kernel stack
by Tao Liu
With kernel patch [1], x86_64 will add extra padding for kernel stack,
as a result, the pt_regs will be shift down by the offset of padding.
Without the patch, the values of registers read from pt_regs will be
incorrect.
Though currently the TOP_OF_KERNEL_STACK_PADDING is configured by
Kconfig, according to kernel code comment [2], the value may be made
dynamicly later. In addition there might be systems compiled without
Kconfig avaliable. So in this patch, we will calculate the value of
TOP_OF_KERNEL_STACK_PADDING.
The calculation is as follows:
1) in startup_64(), there is a lea instruction as:
leaq (__end_init_task - TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE)(%rip), %rsp
2) in rewind_stack_and_make_dead(), there is a lea instruction as:
leaq -PTREGS_SIZE(%rax), %rsp
The disassembled 2 instructions will be like:
1) 0xffffffff93a0007d <startup_64+3>: lea 0x1e03ec4(%rip),%rsp # 0xffffffff95803f48
^^^^^^^^^^^^^^^^^^^^
2) 0xffffffff93a0465a <rewind_stack_and_make_dead+10>: lea -0xa8(%rax),%rsp
^^^^
0xffffffff95803f48 is the value of (__end_init_task -
TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE), and 0xa8 is the value of
PTREGS_SIZE, __end_init_task can be get by symbol reading.
[1]: https://lore.kernel.org/all/170668568261.398.10403890006820046961.tip-bot...
[2]: https://elixir.bootlin.com/linux/v6.9.1/source/arch/x86/include/asm/threa...
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
x86_64.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 82 insertions(+), 2 deletions(-)
diff --git a/x86_64.c b/x86_64.c
index 0c21eb8..43a31c2 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -137,6 +137,7 @@ static orc_entry *orc_find(ulong);
static orc_entry *orc_module_find(ulong);
static ulong ip_table_to_vaddr(ulong);
static void orc_dump(ulong);
+static long top_of_kernel_stack_padding(void);
struct machine_specific x86_64_machine_specific = { 0 };
@@ -4089,7 +4090,8 @@ in_exception_stack:
user_mode_eframe = bt->stacktop - SIZE(pt_regs);
if (last_process_stack_eframe < user_mode_eframe)
x86_64_exception_frame(EFRAME_PRINT, 0, bt->stackbuf +
- (bt->stacktop - bt->stackbase) - SIZE(pt_regs),
+ (bt->stacktop - bt->stackbase) - SIZE(pt_regs) -
+ top_of_kernel_stack_padding(),
bt, ofp);
}
@@ -4410,7 +4412,8 @@ in_exception_stack:
user_mode_eframe = bt->stacktop - SIZE(pt_regs);
if (last_process_stack_eframe < user_mode_eframe)
x86_64_exception_frame(EFRAME_PRINT, 0, bt->stackbuf +
- (bt->stacktop - bt->stackbase) - SIZE(pt_regs),
+ (bt->stacktop - bt->stackbase) - SIZE(pt_regs) -
+ top_of_kernel_stack_padding(),
bt, ofp);
}
@@ -9541,4 +9544,81 @@ x86_64_swp_offset(ulong entry)
return SWP_OFFSET(entry);
}
+static long
+top_of_kernel_stack_padding(void)
+{
+ char buf1[BUFSIZE];
+ char *cursor;
+ long final_value, ptregs_size_value;
+ char *arglist[MAXARGS];
+ bool found = FALSE;
+
+ static long kernel_stack_padding = -1;
+
+ if (kernel_stack_padding >= 0)
+ return kernel_stack_padding;
+
+ /*
+ * startup_64:
+ * ...
+ * mov %rsi,%r15
+ * leaq (__end_init_task - TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE)(%rip), %rsp
+ */
+ sprintf(buf1, "disass /r startup_64");
+ open_tmpfile2();
+ if (!gdb_pass_through(buf1, pc->tmpfile2, GNU_RETURN_ON_ERROR)) {
+ kernel_stack_padding = 0;
+ goto out;
+ }
+
+ rewind(pc->tmpfile2);
+ while (fgets(buf1, BUFSIZE, pc->tmpfile2) && !found) {
+ // machine code of "mov %rsi,%r15"
+ if (strstr(buf1, "49 89 f7"))
+ found = TRUE;
+ }
+ if (!found || !(cursor = strstr(buf1, "# 0x"))) {
+ kernel_stack_padding = 0;
+ goto out;
+ }
+
+ parse_line(cursor, arglist);
+ final_value = stol(arglist[1], FAULT_ON_ERROR, NULL);
+
+ /*
+ * rewind_stack_and_make_dead:
+ * ...
+ * leaq -PTREGS_SIZE(%rax), %rsp
+ */
+ found = FALSE;
+ rewind(pc->tmpfile2);
+ sprintf(buf1, "disass rewind_stack_and_make_dead");
+ if (!gdb_pass_through(buf1, pc->tmpfile2, GNU_RETURN_ON_ERROR)) {
+ kernel_stack_padding = 0;
+ goto out;
+ }
+ rewind(pc->tmpfile2);
+ while (fgets(buf1, BUFSIZE, pc->tmpfile2)) {
+ // find leaq -PTREGS_SIZE(%rax), %rsp
+ if (strstr(buf1, "lea") && (cursor = strstr(buf1, "-0x"))) {
+ parse_line(cursor, arglist);
+ char *p = strchr(arglist[0], '(');
+ *p = '\0';
+ ptregs_size_value = stol(arglist[0] + 1, FAULT_ON_ERROR, NULL);
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found) {
+ kernel_stack_padding = 0;
+ goto out;
+ }
+
+ struct syment *s = symbol_search("__end_init_task");
+ kernel_stack_padding = s->value - final_value - ptregs_size_value;
+out:
+ close_tmpfile2();
+ return kernel_stack_padding;
+}
+
#endif /* X86_64 */
--
2.40.1
4 months, 2 weeks
Re: [PATCH] Reflect __{start,end}_init_task kernel symbols rename
by Lianbo Jiang
Hi, Alexander
Thank you for the early fix.
On 4/10/24 22:15, devel-request(a)lists.crash-utility.osci.io wrote:
> Date: Wed, 10 Apr 2024 14:55:35 +0200
> From: Alexander Gordeev<agordeev(a)linux.ibm.com>
> Subject: [Crash-utility] [PATCH] Reflect __{start,end}_init_task
> kernel symbols rename
> To:devel@lists.crash-utility.osci.io
> Cc: Alexander Egorenkov<egorenar(a)linux.ibm.com>
> Message-ID:<20240410125535.2891355-1-agordeev(a)linux.ibm.com>
>
> Kernel commit 8f69cba096b5 ("x86: Rename __{start,end}_init_task to
> __{start,end}_init_stack") leads to failure:
>
> crash: invalid count request: 0
Could you please point out which command caused the current failure? or
failed when crash load?
Anyway, the code changes are fine to me.
Thanks
Lianbo
> Assume both __{start,end}_init_task and __{start,end}_init_stack
> symbols could exist for backward compatibility.
>
> Signed-off-by: Alexander Gordeev<agordeev(a)linux.ibm.com>
> ---
> task.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/task.c b/task.c
> index ebdb5be..88e1d50 100644
> --- a/task.c
> +++ b/task.c
> @@ -496,10 +496,17 @@ task_init(void)
> ((len = SIZE(thread_union)) != STACKSIZE())) {
> machdep->stacksize = len;
> } else if (!VALID_SIZE(thread_union) && !VALID_SIZE(task_union)) {
> + len = 0;
> if (kernel_symbol_exists("__start_init_task") &&
> kernel_symbol_exists("__end_init_task")) {
> len = symbol_value("__end_init_task");
> len -= symbol_value("__start_init_task");
> + } else if (kernel_symbol_exists("__start_init_stack") &&
> + kernel_symbol_exists("__end_init_stack")) {
> + len = symbol_value("__end_init_stack");
> + len -= symbol_value("__start_init_stack");
> + }
> + if (len) {
> ASSIGN_SIZE(thread_union) = len;
> machdep->stacksize = len;
> }
> -- 2.40.1
4 months, 3 weeks
Re: [PATCH] arm64: section_size_bits compatible with macro definitions
by Lianbo Jiang
On 5/11/24 17:27, devel-request(a)lists.crash-utility.osci.io wrote:
> Date: Sat, 11 May 2024 17:26:48 +0800
> From: Guanyou Chen<chenguanyou9338(a)gmail.com>
> Subject: [Crash-utility] Re: [PATCH] arm64: section_size_bits
> compatible with macro definitions
> To: Lianbo Jiang<lijiang(a)redhat.com>
> Cc:devel@lists.crash-utility.osci.io
> Message-ID:
> <CAHS3RMVaBAwPjxkGk3szxtyK5Brf0cEYe7YrRG4siTo1G9eKdw(a)mail.gmail.com>
> Content-Type: multipart/alternative;
> boundary="00000000000016eb1706182a41ce"
>
> --00000000000016eb1706182a41ce
> Content-Type: text/plain; charset="UTF-8"
> Content-Transfer-Encoding: quoted-printable
>
> Hi Lianbo
>
>> So I'm wondering if this issue occurs on older kernels(e.g. 5.12 or
>> earlier), and probably introduced some latest kernel patches(such as
>> kernel commit f0b13ee23241) to the old kernel. Just want to confirm this.
> Yes, Android12-GKI kernel version 5.10.
Thanks for the information. I have no other issues.
Applied:
https://github.com/crash-utility/crash/commit/568c6f049ad4a20918afeb2db9b...
> Thanks
> Guanyou.Chen
4 months, 4 weeks