----- "Joe Porter" <joe.porter(a)ccur.com> wrote:
> Hello crash,
>
> The user_regs_struct was redefined in
> linux-2.6.24-git8/include/asm-x86/user_32.h.
>
> This results in the following error when opening 32 bit kdump
> crashfiles:
> -------------------------------------------------------------------------
> please wait... (determining panic task)
> crash: invalid structure member offset: user_regs_struct_ebp
> FILE: netdump.c LINE: 687 FUNCTION: get_netdump_panic_task()
>
> [/sbin/crash] error trace: 80e09f4 => 8154159 => 814fc3f => 813ec75
>
> 813ec75: OFFSET_verify+126
> 814fc3f: get_netdump_panic_task+1196
> 8154159: get_kdump_panic_task+11
> 80e09f4: get_dumpfile_panic_task+153
> --------------------------------------------------------------------
>
> I've inserted a patch to crash-4.0-7.4/x86.c that fixes this for all
> linux-2.6.24-git8
> and later kernels (2.6.25 -> 2.6.28-rc5). I've also inserted the
> kernel change that
> caused the breakage.
>
> The fix is bad because it breaks all kernels <= linux-2.6.24-git7.
>
> A better fix would be backward and forward compatible with all
> kernels, but since there
> was a lot of hardwired code revolving around the old 32 bit
> user_regs_struct I thought I
> would just submit this patch to expose the problem and maybe look for
> a better fix in the
> next crash update.
Right -- it wouldn't be a "better fix", but rather the "only
fix"
that's going to be acceptable.
... of course
Does the new kernel that has the name changes end up using the
initial attempts to set the size, esp and ebp offsets? Or does
it always end up using the "if (!VALID_STRUCT())" section? It's
only going to use one or the other, depending upon whether the
user_regs_struct gets exported-to/included-in the debuginfo data.
I did a binary search on all the kernels between 2.6.23 and 2.6.28-rc?.
It was pretty clear that we were always going to get into this after
2.6.24-git8.
After I figured out the names changed, I didn't take it any further than
what you see in the patch.
When I dropped in the new x86_user_regs_struct, the code wouldn't build
without making the two little changes to the MEMBER_OFFSET_INIT calls.
There were a lot of related changes to the elf core code and also in
the 64 bit user_regs_struct.
I assume the 64 bit kdump crashfiles still work either because the crash
initialization code differs or because the 32 bit elf core stuff changed
to cause the !VALID_STRUCT() call to come back true.
I'm really not very familiar with crash and kdump.
I'll attach a git7-git8 diff of some of the related code from asm-x86.
I guess any final fix would need to take into account guarding against
any other future changes like this ... if one could reasonably do so.
I won't have much time to delve into it any more for at least a few more
weeks.
joe
BTW I'm using kexec-tools-2.0.0.tar.gz and the build env is RHEL5.2.
Dave
>
> thx, joe
>
> --- crash-4.0-7.4.orig/x86.c 2008-10-14 09:35:40.000000000 -0400
> +++ crash-4.0-7.4/x86.c 2008-11-17 13:37:40.000000000 -0500
> @@ -1774,29 +1774,39 @@
> machdep->flags |= OMIT_FRAME_PTR;
> STRUCT_SIZE_INIT(user_regs_struct, "user_regs_struct");
> MEMBER_OFFSET_INIT(user_regs_struct_ebp,
> - "user_regs_struct", "ebp");
> + "user_regs_struct", "bp");
> MEMBER_OFFSET_INIT(user_regs_struct_esp,
> - "user_regs_struct", "esp");
> + "user_regs_struct", "sp");
> if (!VALID_STRUCT(user_regs_struct)) {
> /* Use this hardwired version -- sometimes the
> * debuginfo doesn't pick this up even though
> * it exists in the kernel; it shouldn't change.
> */
> struct x86_user_regs_struct {
> - long ebx, ecx, edx, esi, edi, ebp, eax;
> - unsigned short ds, __ds, es, __es;
> - unsigned short fs, __fs, gs, __gs;
> - long orig_eax, eip;
> - unsigned short cs, __cs;
> - long eflags, esp;
> - unsigned short ss, __ss;
> + unsigned long bx;
> + unsigned long cx;
> + unsigned long dx;
> + unsigned long si;
> + unsigned long di;
> + unsigned long bp;
> + unsigned long ax;
> + unsigned long ds;
> + unsigned long es;
> + unsigned long fs;
> + unsigned long gs;
> + unsigned long orig_ax;
> + unsigned long ip;
> + unsigned long cs;
> + unsigned long flags;
> + unsigned long sp;
> + unsigned long ss;
> };
> ASSIGN_SIZE(user_regs_struct) =
> sizeof(struct x86_user_regs_struct);
> ASSIGN_OFFSET(user_regs_struct_ebp) =
> - offsetof(struct x86_user_regs_struct, ebp);
> + offsetof(struct x86_user_regs_struct, bp);
> ASSIGN_OFFSET(user_regs_struct_esp) =
> - offsetof(struct x86_user_regs_struct, esp);
> + offsetof(struct x86_user_regs_struct, sp);
> }
> MEMBER_OFFSET_INIT(thread_struct_cr3, "thread_struct",
"cr3");
> STRUCT_SIZE_INIT(cpuinfo_x86, "cpuinfo_x86");
>
> --------------------------------------------------------------------------------
>
> --- linux-2.6.24-git7/include/asm-x86/user_32.h 2008-01-24
> 17:58:37.000000000 -0500
> +++ linux-2.6.24-git8/include/asm-x86/user_32.h 2008-11-11
> 18:56:13.000000000 -0500
> @@ -75,13 +75,23 @@
> * doesn't use the extra segment registers)
> */
> struct user_regs_struct {
> - long ebx, ecx, edx, esi, edi, ebp, eax;
> - unsigned short ds, __ds, es, __es;
> - unsigned short fs, __fs, gs, __gs;
> - long orig_eax, eip;
> - unsigned short cs, __cs;
> - long eflags, esp;
> - unsigned short ss, __ss;
> + unsigned long bx;
> + unsigned long cx;
> + unsigned long dx;
> + unsigned long si;
> + unsigned long di;
> + unsigned long bp;
> + unsigned long ax;
> + unsigned long ds;
> + unsigned long es;
> + unsigned long fs;
> + unsigned long gs;
> + unsigned long orig_ax;
> + unsigned long ip;
> + unsigned long cs;
> + unsigned long flags;
> + unsigned long sp;
> + unsigned long ss;
> };
>
> /* When the kernel dumps core, it starts by dumping the user struct
> -
>
> --
> Crash-utility mailing list
> Crash-utility(a)redhat.com
>
https://www.redhat.com/mailman/listinfo/crash-utility