[Crash-utility] [PATCH] Improve error handling when architecture doesn't match
Dave Anderson
anderson at redhat.com
Fri Dec 21 14:00:16 UTC 2007
Bernhard Walle wrote:
> Currently, crash prints always
>
> crash: vmcore: not a supported file format
>
> if you try to open a dump file which is not supported. However, it can be
> misleading if you have a valid ELF core dump, but just use crash for the wrong
> architecture. In the case I observed the user had a ELF64 x86 dump file and
> assumed it's x86-64. However, it just was a i386 core dump which was ELF64
> because kexec was called with --elf64-core-headers which makes sense
> if the i386 machine has PAE and possibly more than 4 GiB of physical RAM.
>
> After that patch is applied, an example output is
>
> Looks like a valid ELF dump, but host architecture (X86_64) \
> doesn't match dump architecture (IA64).
>
> or if I try to open a PPC64 dump on x86-64:
>
> Looks like a valid ELF dump, but host endianess (LE) \
> doesn't match target endianess (BE)
>
> Please review and consider applying.
I like the addition of the machine-type verification error message.
But why bother with the endian check? Using your ppc64/x86_64
example, an architecture check/error message would make far
more sense. The "endianness" error message implies that if
they re-compiled their ppc64 kernel little-endian that things
would work.
Dave
>
>
> Signed-off-by: Bernhard Walle <bwalle at suse.de>
>
> ---
> defs.h | 3 ++-
> netdump.c | 48 +++++++++++++++++++++++++++++++++++++++++++-----
> tools.c | 9 ++++++++-
> 3 files changed, 53 insertions(+), 7 deletions(-)
>
> --- a/defs.h
> +++ b/defs.h
> @@ -3198,7 +3198,8 @@ void stall(ulong);
> char *pages_to_size(ulong, char *);
> int clean_arg(void);
> int empty_list(ulong);
> -int machine_type(char *);
> +int machine_type(const char *);
> +int is_big_endian(void);
> void command_not_supported(void);
> void option_not_supported(int);
> void please_wait(char *);
> --- a/netdump.c
> +++ b/netdump.c
> @@ -36,6 +36,32 @@ static void check_dumpfile_size(char *);
> #define ELFREAD 0
>
> #define MIN_PAGE_SIZE (4096)
> +
> +
> +/*
> + * Checks if the machine type of the host matches required_type.
> + * If not, it prints a short error message for the user.
> + */
> +static int machine_type_error(const char *required_type)
> +{
> + if (machine_type(required_type))
> + return 1;
> + else {
> + fprintf(stderr, "Looks like a valid ELF dump, but host "
> + "architecture (%s) doesn't match dump "
> + "architecture (%s).\n",
> + MACHINE_TYPE, required_type);
> + return 0;
> + }
> +}
> +
> +/*
> + * Returns endianess in a string
> + */
> +static const char *endianess_to_string(int big_endian)
> +{
> + return big_endian ? "BE" : "LE";
> +}
>
> /*
> * Determine whether a file is a netdump/diskdump/kdump creation,
> @@ -98,6 +124,18 @@ is_netdump(char *file, ulong source_quer
> * If either kdump difference is seen, presume kdump -- this
> * is obviously subject to change.
> */
> +
> + /* check endianess */
> + if ((STRNEQ(elf32->e_ident, ELFMAG) || STRNEQ(elf64->e_ident, ELFMAG)) &&
> + (elf32->e_type == ET_CORE || elf64->e_type == ET_CORE) &&
> + (elf32->e_ident[EI_DATA] == ELFDATA2LSB && is_big_endian()) ||
> + (elf32->e_ident[EI_DATA] == ELFDATA2MSB && !is_big_endian()))
> + fprintf(stderr, "Looks like a valid ELF dump, but host "
> + "endianess (%s) doesn't match target "
> + "endianess (%s)\n",
> + endianess_to_string(is_big_endian()),
> + endianess_to_string(elf32->e_ident[EI_DATA] == ELFDATA2MSB));
> +
> if (STRNEQ(elf32->e_ident, ELFMAG) &&
> (elf32->e_ident[EI_CLASS] == ELFCLASS32) &&
> (elf32->e_ident[EI_DATA] == ELFDATA2LSB) &&
> @@ -108,7 +146,7 @@ is_netdump(char *file, ulong source_quer
> switch (elf32->e_machine)
> {
> case EM_386:
> - if (machine_type("X86"))
> + if (machine_type_error("X86"))
> break;
> default:
> goto bailout;
> @@ -133,28 +171,28 @@ is_netdump(char *file, ulong source_quer
> {
> case EM_IA_64:
> if ((elf64->e_ident[EI_DATA] == ELFDATA2LSB) &&
> - machine_type("IA64"))
> + machine_type_error("IA64"))
> break;
> else
> goto bailout;
>
> case EM_PPC64:
> if ((elf64->e_ident[EI_DATA] == ELFDATA2MSB) &&
> - machine_type("PPC64"))
> + machine_type_error("PPC64"))
> break;
> else
> goto bailout;
>
> case EM_X86_64:
> if ((elf64->e_ident[EI_DATA] == ELFDATA2LSB) &&
> - machine_type("X86_64"))
> + machine_type_error("X86_64"))
> break;
> else
> goto bailout;
>
> case EM_386:
> if ((elf64->e_ident[EI_DATA] == ELFDATA2LSB) &&
> - machine_type("X86"))
> + machine_type_error("X86"))
> break;
> else
> goto bailout;
> --- a/tools.c
> +++ b/tools.c
> @@ -4518,11 +4518,18 @@ empty_list(ulong list_head_addr)
> }
>
> int
> -machine_type(char *type)
> +machine_type(const char *type)
> {
> return STREQ(MACHINE_TYPE, type);
> }
>
> +int
> +is_big_endian(void)
> +{
> + unsigned short value = 0xff;
> + return *((unsigned char *)&value) != 0xff;
> +}
> +
> void
> command_not_supported()
> {
>
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
More information about the Crash-utility
mailing list