[Crash-utility] 32 bit linux-2.6.24-git8 user_regs_struct change breaks opening kdump crashfiles

Joe Porter joe.porter at ccur.com
Mon Nov 17 22:12:04 UTC 2008


On Mon, 2008-11-17 at 15:30 -0500, Dave Anderson wrote:
> ----- "Joe Porter" <joe.porter at 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 at redhat.com
> > https://www.redhat.com/mailman/listinfo/crash-utility
-------------- next part --------------
A non-text attachment was scrubbed...
Name: user_regs_struct.diff
Type: text/x-patch
Size: 13374 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/crash-utility/attachments/20081117/0c118e4a/attachment.bin>


More information about the Crash-utility mailing list