[Crash-utility] [PATCH] debuginfo does not pick user_regs_struct on x86_64

Dave Anderson anderson at redhat.com
Tue Mar 1 15:58:34 UTC 2011



----- Original Message -----
> On RHEL6(x86_64), debuginfo does not pick user_regs_struct on x86_64.
> 
> # gdb /usr/lib/debug/lib/modules/2.6.32-71.el6.x86_64/vmlinux
> GNU gdb (GDB) Red Hat Enterprise Linux (7.1-29.el6)
> Copyright (C) 2010 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 "x86_64-redhat-linux-gnu".
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>...
> Reading symbols from
> /usr/lib/debug/lib/modules/2.6.32-71.el6.x86_64/vmlinux...done.
> (gdb) ptype struct user_regs_struct
> No struct type named user_regs_struct.
> 
> ---
> x86_64.c | 25 +++++++++++++++++++++++++
> 1 files changed, 25 insertions(+), 0 deletions(-)
> 
> diff --git a/x86_64.c b/x86_64.c
> index a782334..853a1aa 100644
> --- a/x86_64.c
> +++ b/x86_64.c
> @@ -332,6 +332,31 @@ x86_64_init(int when)
> MEMBER_OFFSET_INIT(user_regs_struct_ss,
> "user_regs_struct", "ss");
> STRUCT_SIZE_INIT(user_regs_struct, "user_regs_struct");
> + 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_64_user_regs_struct {
> + unsigned long long r15, r14, r13, r12, bp, bx;
> + unsigned long long r11, r10, r9, r8, ax, cx, dx;
> + unsigned long long si, di, orig_ax, ip, cs;
> + unsigned long long flags, sp, ss, fs_base;
> + unsigned long long gs_base, ds, es, fs, gs;
> + };
> + ASSIGN_SIZE(user_regs_struct) =
> + sizeof(struct x86_64_user_regs_struct);
> + ASSIGN_OFFSET(user_regs_struct_rip) =
> + offsetof(struct x86_64_user_regs_struct, ip);
> + ASSIGN_OFFSET(user_regs_struct_rsp) =
> + offsetof(struct x86_64_user_regs_struct, sp);
> + ASSIGN_OFFSET(user_regs_struct_eflags) =
> + offsetof(struct x86_64_user_regs_struct, flags);
> + ASSIGN_OFFSET(user_regs_struct_cs) =
> + offsetof(struct x86_64_user_regs_struct, cs);
> + ASSIGN_OFFSET(user_regs_struct_ss) =
> + offsetof(struct x86_64_user_regs_struct, ss);
> + }
> machdep->vmalloc_start = x86_64_vmalloc_start;
> vt->vmalloc_start = machdep->vmalloc_start();
> machdep->init_kernel_pgd();
> --
> 1.7.1

Right -- over the years it has been "found" in some kernel
version's debuginfo data, but certainly not in all kernel
versions.  (mostly not) 
  
But anyway, its potential non-existence has been worked
around such that the offset_table entries are not required.  

I did test it out on ~150 sample dumpfiles, and while it doesn't
break anything, it doesn't help either -- the "bt -a" output is
identical with or without the patch.

Did you actually have a situation where a backtrace failed
without it -- but then worked OK with your patch?

And was there a reason you used "unsigned long long" declarations?
I understand they are the same, but the kernel uses "unsigned long".
Why the difference?

Dave







More information about the Crash-utility mailing list