public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* dwarf2 frame unwinder assumptions on SP
@ 2005-07-11 14:44 Christophe LYON
  2005-07-11 14:51 ` Daniel Jacobowitz
  0 siblings, 1 reply; 10+ messages in thread
From: Christophe LYON @ 2005-07-11 14:44 UTC (permalink / raw)
  To: gdb


Hi all,

I am working on the connection of the dwarf2 frame unwinder
to our GDB port, and I have trouble with some assumptions
made by GDB about SP.

Currently, in my x-tdep.c I have:
  set_gdbarch_unwind_pc(gdbarch, x_unwind_pc);
  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);

This improves the backtracing capability (especially in presence
of alloca()), but exhibits many regressions when displaying the
parameters of functions called. (eg gdb.base/funcargs)

I have isolated the reason of failure, but don't know how to
solve it cleanly.

In the debug_info section, the call6b() function has:
DW_AT_frame_base            DW_OP_bregx12+48
(register 12 is our SP)
and the 1st parameter of call6b() has:
DW_AT_location              DW_OP_fbreg -16

The frame_base described here is the value of SP upon
entry in call6b().

In the debug_frame section, in CIE, we have:
DW_CFA_def_cfa: r12 ofs 16

which means that our CFA is SP + 16 upon function entry.


Now, when 'backtrace' looks for the value of the 1st parameter,
it needs to recompute the value of SP.
The default for this is provided by
frame2-frame.c:dwarf2_frame_default_init_reg() to:
  ...
  else if (regnum == SP_REGNUM)
    reg->how = DWARF2_FRAME_REG_CFA;

which leads to my trouble.

The comes from an assumption about the GCC behaviour and
the Dwarf spec saying that "Typically, the CFA is defined
to be the value of the stack pointer at the call site in
the previous frame" which does not hold for our
target/ABI (the compiler is Open64).

I would like to express that SP is CFA-16, but I don't
see how to achieve that.

Indeed, in dwarf2-frame.c:dwarf2_frame_prev_register(),
no code would enable the beheviour I want. I thought of
using DWARF2_FRAME_REG_SAVED_EXP but it involves an extra
indirection.

The possibilities I can think of are as follows:
1 - add a case like DWARF2_FRAME_REG_CFA_OFFSET
    in dwarf2-frame.[ch] to do what I need

2 - copy a large part of the generic support from
    dwarf2-frame.c into x-tdep.c to have a customized
    x_frame_prev_register()

3 - have a specific dwarf2_sniffer / frame_prev_register
    that calls the generic code, except for SP (still
    not clear how to do that cleanly, as most of the functions
    I need to call are 'static')

4 - modify the compiler so that DW_AT_frame_base takes into
    account the missing 16 bytes and thus have frame_base == CFA
    but frame_base != SP. I fear this will lead to trouble
    further....

5 - modify the compiler / libdwarf so that it makes use of the
    Dwarf3 operators such as DW_CFA_offset_extended_sf which
    allow for signed offsets (which, basically is the reason
    for having CFA != SP: in our ABI, the caller reserves 16 bytes
    on the stack for callee usage)


I hope my description is clear enough so that someone can help me.

Thanks,

Christophe.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: dwarf2 frame unwinder assumptions on SP
  2005-07-11 14:44 dwarf2 frame unwinder assumptions on SP Christophe LYON
@ 2005-07-11 14:51 ` Daniel Jacobowitz
  2005-07-11 15:33   ` Christophe LYON
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel Jacobowitz @ 2005-07-11 14:51 UTC (permalink / raw)
  To: Christophe LYON; +Cc: gdb

On Mon, Jul 11, 2005 at 04:43:55PM +0200, Christophe LYON wrote:
> 
> Hi all,
> 
> I am working on the connection of the dwarf2 frame unwinder
> to our GDB port, and I have trouble with some assumptions
> made by GDB about SP.
> 
> Currently, in my x-tdep.c I have:
>   set_gdbarch_unwind_pc(gdbarch, x_unwind_pc);
>   frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);

It sounds like you need to set a "frame base" sniffer also, other than
the dwarf one.  The dwarf2 frame unwinder does not set anything related
to the "frame base" used by symbolic debug information; it only unwinds
the stack pointer as best it can.

Does "print $sp" work correctly when unwinding?


-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: dwarf2 frame unwinder assumptions on SP
  2005-07-11 14:51 ` Daniel Jacobowitz
@ 2005-07-11 15:33   ` Christophe LYON
  2005-07-11 15:47     ` Daniel Jacobowitz
  0 siblings, 1 reply; 10+ messages in thread
From: Christophe LYON @ 2005-07-11 15:33 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb


> > Currently, in my x-tdep.c I have:
> >   set_gdbarch_unwind_pc(gdbarch, x_unwind_pc);
> >   frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
> 
> It sounds like you need to set a "frame base" sniffer also, other than
> the dwarf one.  The dwarf2 frame unwinder does not set anything related
> to the "frame base" used by symbolic debug information; it only unwinds
> the stack pointer as best it can.
> 
> Does "print $sp" work correctly when unwinding?
> 

At frame #0, it's OK, at frame #1 it is not (it displays CFA).

I have tried to add
  frame_base_set_default (gdbarch, &x_frame_base);

where
static CORE_ADDR
x_frame_base_address (struct frame_info *next_frame, void **this_cache)
{
  struct lx_frame_cache *cache = x_frame_cache (next_frame, this_cache);
  fprintf(stderr, "In %s\n", __FUNCTION__);

  return cache->base;
}

static const struct frame_base x_frame_base =
{
  &x_frame_unwind,
  x_frame_base_address,
  x_frame_base_address,
  x_frame_base_address
};

but in my test case x_frame_base_address() is not called.
(in funcargs, I set a bkp in call6b, run, then backtrace)

Isn't this what you mean by "frame base sniffer" ?

Thanks,

Christophe.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: dwarf2 frame unwinder assumptions on SP
  2005-07-11 15:33   ` Christophe LYON
@ 2005-07-11 15:47     ` Daniel Jacobowitz
  2005-07-11 15:58       ` Christophe LYON
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel Jacobowitz @ 2005-07-11 15:47 UTC (permalink / raw)
  To: Christophe LYON; +Cc: gdb

On Mon, Jul 11, 2005 at 05:32:15PM +0200, Christophe LYON wrote:
> 
> > > Currently, in my x-tdep.c I have:
> > >   set_gdbarch_unwind_pc(gdbarch, x_unwind_pc);
> > >   frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
> > 
> > It sounds like you need to set a "frame base" sniffer also, other than
> > the dwarf one.  The dwarf2 frame unwinder does not set anything related
> > to the "frame base" used by symbolic debug information; it only unwinds
> > the stack pointer as best it can.
> > 
> > Does "print $sp" work correctly when unwinding?
> > 
> 
> At frame #0, it's OK, at frame #1 it is not (it displays CFA).

Then you've got an unwinding problem.  Your unwind information is not
providing adequate information to recreate the value of $sp, so
adjusting the frame base isn't going to help after all.

You probably want to provide an init_reg method which does something
clever with SP_REGNUM.  You may get the easiest results by adjusting
DWARF2_FRAME_REG_CFA to support an offset, i.e., set $sp to the value
of the CFA plus some fixed offset.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: dwarf2 frame unwinder assumptions on SP
  2005-07-11 15:47     ` Daniel Jacobowitz
@ 2005-07-11 15:58       ` Christophe LYON
  2005-07-11 16:03         ` Daniel Jacobowitz
  0 siblings, 1 reply; 10+ messages in thread
From: Christophe LYON @ 2005-07-11 15:58 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb


> > > > Currently, in my x-tdep.c I have:
> > > >   set_gdbarch_unwind_pc(gdbarch, x_unwind_pc);
> > > >   frame_unwind_append_sniffer (gdbarch, 
> > >
> > > It sounds like you need to set a "frame base" sniffer also, other than
> > > the dwarf one.  The dwarf2 frame unwinder does not set anything related
> > > to the "frame base" used by symbolic debug information; it only unwinds
> > > the stack pointer as best it can.
> > >
> > > Does "print $sp" work correctly when unwinding?
> > >
> >
> > At frame #0, it's OK, at frame #1 it is not (it displays CFA).
> 
> Then you've got an unwinding problem.  Your unwind information is not
> providing adequate information to recreate the value of $sp, so
> adjusting the frame base isn't going to help after all.
> 
> You probably want to provide an init_reg method which does something
> clever with SP_REGNUM.  You may get the easiest results by adjusting
> DWARF2_FRAME_REG_CFA to support an offset, i.e., set $sp to the value
> of the CFA plus some fixed offset.
> 

I don't see what to do in init_reg without adding a new value to the
dwarf2_frame_reg_rule enum. Do you mean changing the semantics of
DWARF2_FRAME_REG_CFA and provide a frame_prev_register() method
to interpret it accordingly?

If the latter, it also means I have to write a specific frame_sniffer()
to return the frame_unwind struct pointing to my frame_prev_register()
method, right?

Then, it sounds like my frame_sniffer() should replace
dwarf2_frame_sniffer()
but use the same code, as I only want to replace frame_prev_register().
Am I right?

Thanks,

Christophe.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: dwarf2 frame unwinder assumptions on SP
  2005-07-11 15:58       ` Christophe LYON
@ 2005-07-11 16:03         ` Daniel Jacobowitz
  2005-07-11 17:02           ` Richard Henderson
  2005-07-11 19:47           ` Mark Kettenis
  0 siblings, 2 replies; 10+ messages in thread
From: Daniel Jacobowitz @ 2005-07-11 16:03 UTC (permalink / raw)
  To: Christophe LYON; +Cc: gdb

On Mon, Jul 11, 2005 at 05:58:14PM +0200, Christophe LYON wrote:
> I don't see what to do in init_reg without adding a new value to the
> dwarf2_frame_reg_rule enum. Do you mean changing the semantics of
> DWARF2_FRAME_REG_CFA and provide a frame_prev_register() method
> to interpret it accordingly?

No.  Change it globally in dwarf2-frame.c, since the offset field is
currently unused with that rule.

I have the nagging feeling this has come up before, but I can't
remember the conclusion.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: dwarf2 frame unwinder assumptions on SP
  2005-07-11 16:03         ` Daniel Jacobowitz
@ 2005-07-11 17:02           ` Richard Henderson
  2005-07-11 17:06             ` Daniel Jacobowitz
  2005-07-11 19:47           ` Mark Kettenis
  1 sibling, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2005-07-11 17:02 UTC (permalink / raw)
  To: Christophe LYON, gdb

On Mon, Jul 11, 2005 at 12:03:34PM -0400, Daniel Jacobowitz wrote:
> I have the nagging feeling this has come up before, but I can't
> remember the conclusion.

That dwarf2 doesn't have the proper codes to represent anything
other than entry-sp-equals-cfa and entry-sp-stored-on-stack.


r~

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: dwarf2 frame unwinder assumptions on SP
  2005-07-11 17:02           ` Richard Henderson
@ 2005-07-11 17:06             ` Daniel Jacobowitz
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel Jacobowitz @ 2005-07-11 17:06 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Christophe LYON, gdb

On Mon, Jul 11, 2005 at 10:02:36AM -0700, Richard Henderson wrote:
> On Mon, Jul 11, 2005 at 12:03:34PM -0400, Daniel Jacobowitz wrote:
> > I have the nagging feeling this has come up before, but I can't
> > remember the conclusion.
> 
> That dwarf2 doesn't have the proper codes to represent anything
> other than entry-sp-equals-cfa and entry-sp-stored-on-stack.

That's right, but I meant the change to GDB's internal representation
specifically.

BTW, the latest dwarf3 draft does include appropriate unwinding rules
for register = cfa + value, along with a couple of other useful ones. 
That draft isn't publicly available yet, but see here:

http://dwarf.freestandards.org/ShowIssue.php?issue=030812.2&type=closed

-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: dwarf2 frame unwinder assumptions on SP
  2005-07-11 16:03         ` Daniel Jacobowitz
  2005-07-11 17:02           ` Richard Henderson
@ 2005-07-11 19:47           ` Mark Kettenis
  2005-07-12 14:05             ` Christophe LYON
  1 sibling, 1 reply; 10+ messages in thread
From: Mark Kettenis @ 2005-07-11 19:47 UTC (permalink / raw)
  To: drow; +Cc: christophe.lyon, gdb

   Date: Mon, 11 Jul 2005 12:03:34 -0400
   From: Daniel Jacobowitz <drow@false.org>

   On Mon, Jul 11, 2005 at 05:58:14PM +0200, Christophe LYON wrote:
   > I don't see what to do in init_reg without adding a new value to the
   > dwarf2_frame_reg_rule enum. Do you mean changing the semantics of
   > DWARF2_FRAME_REG_CFA and provide a frame_prev_register() method
   > to interpret it accordingly?

   No.  Change it globally in dwarf2-frame.c, since the offset field is
   currently unused with that rule.

It's probably better to introduce DWARF2_FRAME_REG_CFA_OFFSET just
like we did for DWARF2_FRAME_REG_RA_OFFSET.  That would be #1 on your
list, Christophe.

   I have the nagging feeling this has come up before, but I can't
   remember the conclusion.

In the past we have discussed the relation between DW_OP_fbreg and
CFA; some GCC port was never defining the frame base, and someone
tried to use CFA.  The conclusion then was that the CFA is defined
only for the call frame info.  This is why #4 on Christophe's list
isn't the way to go.

Mark

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: dwarf2 frame unwinder assumptions on SP
  2005-07-11 19:47           ` Mark Kettenis
@ 2005-07-12 14:05             ` Christophe LYON
  0 siblings, 0 replies; 10+ messages in thread
From: Christophe LYON @ 2005-07-12 14:05 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: drow, gdb

Mark Kettenis wrote:
> 
>    Date: Mon, 11 Jul 2005 12:03:34 -0400
>    From: Daniel Jacobowitz <drow@false.org>
> 
>    On Mon, Jul 11, 2005 at 05:58:14PM +0200, Christophe LYON wrote:
>    > I don't see what to do in init_reg without adding a new value to the
>    > dwarf2_frame_reg_rule enum. Do you mean changing the semantics of
>    > DWARF2_FRAME_REG_CFA and provide a frame_prev_register() method
>    > to interpret it accordingly?
> 
>    No.  Change it globally in dwarf2-frame.c, since the offset field is
>    currently unused with that rule.
> 
> It's probably better to introduce DWARF2_FRAME_REG_CFA_OFFSET just
> like we did for DWARF2_FRAME_REG_RA_OFFSET.  That would be #1 on your
> list, Christophe.
> 

OK thanks. That way my preferred solution, but needed approval before
proceeding. It's very similar to what Daniel suggested, and works
well.

Christophe.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2005-07-12 14:05 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-11 14:44 dwarf2 frame unwinder assumptions on SP Christophe LYON
2005-07-11 14:51 ` Daniel Jacobowitz
2005-07-11 15:33   ` Christophe LYON
2005-07-11 15:47     ` Daniel Jacobowitz
2005-07-11 15:58       ` Christophe LYON
2005-07-11 16:03         ` Daniel Jacobowitz
2005-07-11 17:02           ` Richard Henderson
2005-07-11 17:06             ` Daniel Jacobowitz
2005-07-11 19:47           ` Mark Kettenis
2005-07-12 14:05             ` Christophe LYON

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).