[Crash-utility] [PATCH v2] x86_64: Add Linux 5.8+ exception functions to check exception frame

lijiang lijiang at redhat.com
Fri Apr 16 01:42:04 UTC 2021


在 2021年04月16日 07:56, HAGIO KAZUHITO(萩尾 一仁) 写道:
> Fix for 'bt' command and options on Linux 5.8-rc1 and later kernels
> that contain merge commit 076f14be7fc942e112c94c841baec44124275cd0.
> The merged patches changed the name of exception functions that
> have been used by the crash utility to check the exception frame.
> Without the patch, the command and options cannot display it.
> 
> Before:
>   crash> bt
>   PID: 8752   TASK: ffff8f80cb244380  CPU: 2   COMMAND: "insmod"
>    #0 [ffffa3e40187f9f8] machine_kexec at ffffffffab25d267
>    #1 [ffffa3e40187fa48] __crash_kexec at ffffffffab38e2ed
>    #2 [ffffa3e40187fb10] crash_kexec at ffffffffab38f1dd
>    #3 [ffffa3e40187fb28] oops_end at ffffffffab222cbd
>    #4 [ffffa3e40187fb48] do_trap at ffffffffab21fea1
>    #5 [ffffa3e40187fb90] do_error_trap at ffffffffab21ff75
>    #6 [ffffa3e40187fbd0] exc_invalid_op at ffffffffabb76a2c
>    #7 [ffffa3e40187fbf0] asm_exc_invalid_op at ffffffffabc00a72
>    #8 [ffffa3e40187fc78] init_module at ffffffffc042b018 [invalid]
>    #9 [ffffa3e40187fca0] init_module at ffffffffc042b018 [invalid]
>   #10 [ffffa3e40187fca8] do_one_initcall at ffffffffab202806
>   #11 [ffffa3e40187fd18] do_init_module at ffffffffab3888ba
>   #12 [ffffa3e40187fd38] load_module at ffffffffab38afde
> 
> After:
>   crash> bt
>   PID: 8752   TASK: ffff8f80cb244380  CPU: 2   COMMAND: "insmod"
>    #0 [ffffa3e40187f9f8] machine_kexec at ffffffffab25d267
>    #1 [ffffa3e40187fa48] __crash_kexec at ffffffffab38e2ed
>    #2 [ffffa3e40187fb10] crash_kexec at ffffffffab38f1dd
>    #3 [ffffa3e40187fb28] oops_end at ffffffffab222cbd
>    #4 [ffffa3e40187fb48] do_trap at ffffffffab21fea1
>    #5 [ffffa3e40187fb90] do_error_trap at ffffffffab21ff75
>    #6 [ffffa3e40187fbd0] exc_invalid_op at ffffffffabb76a2c
>    #7 [ffffa3e40187fbf0] asm_exc_invalid_op at ffffffffabc00a72
>       [exception RIP: init_module+24]
>       RIP: ffffffffc042b018  RSP: ffffa3e40187fca8  RFLAGS: 00010246
>       RAX: 000000000000001c  RBX: 0000000000000000  RCX: 0000000000000000
>       RDX: 0000000000000000  RSI: ffff8f80fbd18000  RDI: ffff8f80fbd18000
>       RBP: ffffffffc042b000   R8: 000000000000029d   R9: 000000000000002c
>       R10: 0000000000000000  R11: ffffa3e40187fb58  R12: ffffffffc042d018
>       R13: ffffa3e40187fdf0  R14: ffffffffc042d000  R15: ffffa3e40187fe90
>       ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
>    #8 [ffffa3e40187fca0] init_module at ffffffffc042b018 [invalid]
>    #9 [ffffa3e40187fca8] do_one_initcall at ffffffffab202806
>   #10 [ffffa3e40187fd18] do_init_module at ffffffffab3888ba
>   #11 [ffffa3e40187fd38] load_module at ffffffffab38afde
> 
> Signed-off-by: Kazuhito Hagio <k-hagio-ab at nec.com>
> ---
> v1 -> v2
> - removed "xen_" prefix from "xen_asm_exc_debug"
> 

Thank you for the update.
Acked-by: Lianbo Jiang <lijiang at redhat.com>

>  defs.h   |  1 +
>  x86_64.c | 43 ++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 41 insertions(+), 3 deletions(-)
> 
> diff --git a/defs.h b/defs.h
> index c29b3fa3dee9..f9c711c19d91 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -6026,6 +6026,7 @@ struct machine_specific {
>  	ulong cpu_entry_area_start;
>  	ulong cpu_entry_area_end;
>  	ulong page_offset_force;
> +	char **exception_functions;
>  };
>  
>  #define KSYMS_START    (0x1)
> diff --git a/x86_64.c b/x86_64.c
> index f5b2f7b5f040..d54a3960db36 100644
> --- a/x86_64.c
> +++ b/x86_64.c
> @@ -139,6 +139,9 @@ static void orc_dump(ulong);
>  
>  struct machine_specific x86_64_machine_specific = { 0 };
>  
> +static const char *exception_functions_orig[];
> +static const char *exception_functions_5_8[];
> +
>  /*
>   *  Do all necessary machine-specific setup here.  This is called several
>   *  times during initialization.
> @@ -735,6 +738,12 @@ x86_64_init(int when)
>  		STRUCT_SIZE_INIT(percpu_data, "percpu_data");
>  
>  		GART_init();
> +
> +		if (kernel_symbol_exists("asm_exc_divide_error"))
> +			machdep->machspec->exception_functions = (char **)exception_functions_5_8;
> +		else
> +			machdep->machspec->exception_functions = (char **)exception_functions_orig;
> +
>  		break;
>  
>  	case POST_VM:
> @@ -1104,6 +1113,12 @@ x86_64_dump_machdep_table(ulong arg)
>  		fprintf(fp, "%016lx\n", (ulong)ms->cpu_entry_area_end);
>  	else
>  		fprintf(fp, "(unused)\n");
> +
> +	fprintf(fp, "      excpetion_functions: ");
> +	if (ms->exception_functions == (char **)exception_functions_5_8)
> +		fprintf(fp, "excpetion_functions_5_8\n");
> +	else
> +		fprintf(fp, "excpetion_functions_orig\n");
>  }
>  
>  /*
> @@ -3086,7 +3101,7 @@ text_lock_function(char *name, struct bt_info *bt, ulong locktext)
>   * zeroentry xen_debug do_debug
>   * zeroentry xen_int3 do_int3
>  */
> -static const char *exception_functions[] = {
> +static const char *exception_functions_orig[] = {
>  	"invalid_TSS",
>  	"segment_not_present",
>  	"alignment_check",
> @@ -3109,6 +3124,28 @@ static const char *exception_functions[] = {
>  	NULL,
>  };
>  
> +static const char *exception_functions_5_8[] = {
> +	"asm_exc_invalid_tss",
> +	"asm_exc_segment_not_present",
> +	"asm_exc_alignment_check",
> +	"asm_exc_general_protection",
> +	"asm_exc_page_fault",
> +	"asm_exc_divide_error",
> +	"asm_exc_overflow",
> +	"asm_exc_bounds",
> +	"asm_exc_invalid_op",
> +	"asm_exc_device_not_available",
> +	"asm_exc_coproc_segment_overrun",
> +	"asm_exc_spurious_interrupt_bug",
> +	"asm_exc_coprocessor_error",
> +	"asm_exc_simd_coprocessor_error",
> +	"asm_exc_debug",
> +	"xen_asm_exc_stack_segment",
> +	"xen_asm_exc_xen_hypervisor_callback",
> +	"xen_asm_exc_int3",
> +	NULL,
> +};
> +
>  /*
>   *  print one entry of a stack trace
>   */
> @@ -3185,8 +3222,8 @@ x86_64_print_stack_entry(struct bt_info *bt, FILE *ofp, int level,
>  	if ((THIS_KERNEL_VERSION >= LINUX(2,6,29)) && 
>  	    (eframe_check == -1) && offset && 
>  	    !(bt->flags & (BT_EXCEPTION_FRAME|BT_START|BT_SCHEDULE))) { 
> -		for (i = 0; exception_functions[i]; i++) {
> -			if (STREQ(name, exception_functions[i])) {
> +		for (i = 0; machdep->machspec->exception_functions[i]; i++) {
> +			if (STREQ(name, machdep->machspec->exception_functions[i])) {
>  				eframe_check = 8;
>  				break;
>  			}
> 




More information about the Crash-utility mailing list