* dwarf2 and frame bases
@ 2004-11-10 23:57 Randolph Chung
2004-11-10 23:58 ` Daniel Jacobowitz
0 siblings, 1 reply; 9+ messages in thread
From: Randolph Chung @ 2004-11-10 23:57 UTC (permalink / raw)
To: gdb
The "recurse" test has been failing on hppa for a long time. I think I
finally understand what is happening, but not sure of a fix....
the symptom of the problem is that watchpoints fail during recursion:
(gdb) watch b
Watchpoint 2: b
(gdb) continue
Continuing.
Watchpoint 2: b
Old value = 0
New value = 10
recurse (a=10) at ../../../gdb-cvs/gdb/testsuite/gdb.base/recurse.c:19
19 b *= recurse (a - 1);
(gdb) continue
Continuing.
Error evaluating expression for watchpoint 2
Cannot access memory at address 0x8
Watchpoint 2 deleted.
hppa-linux uses dwarf2, and doesn't implement hardware watchpoints.
The dwarf2 description for recurse looks like this:
<1><a1d>: Abbrev Number: 2 (DW_TAG_subprogram)
DW_AT_sibling : <a53>
DW_AT_name : recurse
DW_AT_decl_file : 1
DW_AT_decl_line : 12
DW_AT_type : <a53>
DW_AT_low_pc : 0x10518
DW_AT_high_pc : 0x10598
DW_AT_frame_base : 1 byte block: 53 (DW_OP_reg3)
<2><a3a>: Abbrev Number: 3 (DW_TAG_formal_parameter)
DW_AT_name : a
DW_AT_decl_file : 1
DW_AT_decl_line : 10
DW_AT_type : <a53>
DW_AT_location : 2 byte block: 91 5c (DW_OP_fbreg: -36)
<2><a46>: Abbrev Number: 4 (DW_TAG_variable)
DW_AT_name : b
DW_AT_decl_file : 1
DW_AT_decl_line : 13
DW_AT_type : <a53>
DW_AT_location : 2 byte block: 91 8 (DW_OP_fbreg: 8)
what seems to happen is that, to implement the watchpoint, we singlestep
through the code and evaluate 'b' at every insn. If we do this in the
prologue, we fail. The dwarf location expression handler tries to get
the frame base by using DW_AT_frame_base, which points to register 3,
but register 3 is not yet initialized in the prologue, so when we read
it, we get garbage. argh...
I don't know enough about dwarf to know how this is supposed to be
evaluated. Can someone please shed some light on this?
thanks
randolph
--
Randolph Chung
Debian GNU/Linux Developer, hppa/ia64 ports
http://www.tausq.org/
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: dwarf2 and frame bases 2004-11-10 23:57 dwarf2 and frame bases Randolph Chung @ 2004-11-10 23:58 ` Daniel Jacobowitz 2004-11-11 3:09 ` Randolph Chung 0 siblings, 1 reply; 9+ messages in thread From: Daniel Jacobowitz @ 2004-11-10 23:58 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb On Wed, Nov 10, 2004 at 03:51:49PM -0800, Randolph Chung wrote: > The "recurse" test has been failing on hppa for a long time. I think I > finally understand what is happening, but not sure of a fix.... > > the symptom of the problem is that watchpoints fail during recursion: > > (gdb) watch b > Watchpoint 2: b > (gdb) continue > Continuing. > Watchpoint 2: b > > Old value = 0 > New value = 10 > recurse (a=10) at ../../../gdb-cvs/gdb/testsuite/gdb.base/recurse.c:19 > 19 b *= recurse (a - 1); > (gdb) continue > Continuing. > Error evaluating expression for watchpoint 2 > Cannot access memory at address 0x8 > Watchpoint 2 deleted. > DW_AT_frame_base : 1 byte block: 53 (DW_OP_reg3) > what seems to happen is that, to implement the watchpoint, we singlestep > through the code and evaluate 'b' at every insn. If we do this in the > prologue, we fail. The dwarf location expression handler tries to get > the frame base by using DW_AT_frame_base, which points to register 3, > but register 3 is not yet initialized in the prologue, so when we read > it, we get garbage. argh... > > I don't know enough about dwarf to know how this is supposed to be > evaluated. Can someone please shed some light on this? 'b' is in some particular frame. It's up the stack from the current frame at the time of that error message, I get. So we should be unwinding reg3 and using the unwound copy to determine the value of b. Is the unwinding breaking? What's the actual PC at the time of the error? Is it in the prologue? Epilogue? What's the stack pointer - at the time of setting the watchpoint, and at the time of the error? -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: dwarf2 and frame bases 2004-11-10 23:58 ` Daniel Jacobowitz @ 2004-11-11 3:09 ` Randolph Chung 2004-11-11 9:57 ` Daniel Jacobowitz 0 siblings, 1 reply; 9+ messages in thread From: Randolph Chung @ 2004-11-11 3:09 UTC (permalink / raw) To: gdb > 'b' is in some particular frame. It's up the stack from the current > frame at the time of that error message, I get. So we should be > unwinding reg3 and using the unwound copy to determine the value of b. > Is the unwinding breaking? but the unwound copy is wrong too... :) i explain more below.. > What's the actual PC at the time of the error? Is it in the prologue? first insn of the prologue. > Epilogue? What's the stack pointer - at the time of setting the > watchpoint, and at the time of the error? well, the frame_base dwarf descriptor points to r3, but the stack pointer is actually r30. r3 is the frame pointer. when compiled without optimization, gcc emits these prologues/epilogues for each function: prologue: stw rp, -14(%sp) copy %r3, %r1 copy %r30, %r3 stw,ma %r1, 80(%sp) /* or other frame size) epilogue: ldw -14(%r3), %rp ldw,mb -80(%sp), %r3 (remember also that on hppa the frame grows towards higher addresses) so in the function body, r3 is the frame base. 'b' is at *(r3 + 8) r3 is also a callee-saved register, so its contents are undefined on entry to the function. so even if you were to unwind r3, you won't get the right frame base. randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: dwarf2 and frame bases 2004-11-11 3:09 ` Randolph Chung @ 2004-11-11 9:57 ` Daniel Jacobowitz 2004-11-11 17:12 ` Randolph Chung 0 siblings, 1 reply; 9+ messages in thread From: Daniel Jacobowitz @ 2004-11-11 9:57 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb On Wed, Nov 10, 2004 at 04:09:33PM -0800, Randolph Chung wrote: > > 'b' is in some particular frame. It's up the stack from the current > > frame at the time of that error message, I get. So we should be > > unwinding reg3 and using the unwound copy to determine the value of b. > > Is the unwinding breaking? > > but the unwound copy is wrong too... :) i explain more below.. Then, that's a bug in the unwinder. > r3 is also a callee-saved register, so its contents are undefined on > entry to the function. so even if you were to unwind r3, you won't get > the right frame base. That's your mistake. At the first instruction of the prologue, unwinding r3 for the previous frame should use the copy already in r3; you need to be falling back to a prologue analyzer and cutting it off at $pc. I thought you already were? -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: dwarf2 and frame bases 2004-11-11 9:57 ` Daniel Jacobowitz @ 2004-11-11 17:12 ` Randolph Chung 2004-11-11 19:42 ` Daniel Jacobowitz 2004-11-11 19:47 ` Mark Kettenis 0 siblings, 2 replies; 9+ messages in thread From: Randolph Chung @ 2004-11-11 17:12 UTC (permalink / raw) To: gdb > > but the unwound copy is wrong too... :) i explain more below.. > > Then, that's a bug in the unwinder. after a night's sleep and some more looking through the code, this is making a bit more sense... > > r3 is also a callee-saved register, so its contents are undefined on > > entry to the function. so even if you were to unwind r3, you won't get > > the right frame base. > > That's your mistake. At the first instruction of the prologue, > unwinding r3 for the previous frame should use the copy already in > r3; you need to be falling back to a prologue analyzer and cutting it > off at $pc. I thought you already were? yes, but... so, if you are at the first insn of the prologue, and you unwind r3, you would get the *previous frame*'s frame base. if you used this value to calculate the address of your locals, you will get the value they have in the previous frame. sounds like it should still work (i.e it should still be a valid address), except the hppa targer has an explicit check for when we expect r3 to be modified but we may be in the process of changing it (since it's a 3 insn sequence). In that case, we zero the register to tell the unwinder not to use the value in the r3 to calculate the frame base (it uses the stack pointer and other unwind information in that case) See http://sources.redhat.com/ml/gdb-patches/2004-06/msg00108.html for more details. i know it is kind of hacky, but the frame unwinding code is explicitly asking "what is the frame base of this frame", and the target code is especially tuned for that..... i see two possible solutions: 1) perhaps the hppa target should use some other mechanism (instead of mucking with r3) to tell the next frame that the frame pointer is not available..... 2) in the dwarf code, when trying to get the frame base, should we explicitly ask for the frame base instead of using the dwarf expression? perhaps this could be something that can be overridden by the target, so that the default still uses the dwarf information. randolph -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: dwarf2 and frame bases 2004-11-11 17:12 ` Randolph Chung @ 2004-11-11 19:42 ` Daniel Jacobowitz 2004-11-11 22:58 ` Randolph Chung 2004-11-11 19:47 ` Mark Kettenis 1 sibling, 1 reply; 9+ messages in thread From: Daniel Jacobowitz @ 2004-11-11 19:42 UTC (permalink / raw) To: Randolph Chung; +Cc: gdb On Thu, Nov 11, 2004 at 08:48:52AM -0800, Randolph Chung wrote: > so, if you are at the first insn of the prologue, and you unwind r3, you > would get the *previous frame*'s frame base. if you used this value to > calculate the address of your locals, you will get the value they have > in the previous frame. Correct. A watchpoint on "b" is associate with a particular frame, because it's a local. You want the previous frame's copy. You get the previous frame's copy. Everyone wins. > sounds like it should still work (i.e it should still be a valid > address), except the hppa targer has an explicit check for when we > expect r3 to be modified but we may be in the process of changing it > (since it's a 3 insn sequence). In that case, we zero the register to > tell the unwinder not to use the value in the r3 to calculate the frame > base (it uses the stack pointer and other unwind information in that > case) > > See http://sources.redhat.com/ml/gdb-patches/2004-06/msg00108.html for > more details. This sounds totally messed up. Suppose we're in frame A, called from frame B. We're at the first instruction. If we ask the sentinel frame to unwind the value of r3, we'll get its real register value - regardless of where we are in the sequence. If we ask frame A to unwind r3, we want to get frame B's r3. Where frame A is in its prologue has no effect on what frame B's r3 was at the time of calling A. There's no more details in that message, just a patch :-) I can't trace exactly what it's doing. > i know it is kind of hacky, but the frame unwinding code is explicitly > asking "what is the frame base of this frame", and the target code is > especially tuned for that..... > > i see two possible solutions: > 1) perhaps the hppa target should use some other mechanism (instead of > mucking with r3) to tell the next frame that the frame pointer is > not available..... The next frame's frame pointer _is_ available. This is what I don't understand. You were asked, "unwind r3 for frame B" and instead you're zeroing it based on where frame A is? > 2) in the dwarf code, when trying to get the frame base, should we > explicitly ask for the frame base instead of using the dwarf > expression? perhaps this could be something that can be overridden > by the target, so that the default still uses the dwarf information. No. The "frame base" as a GDB concept is completely separate from DW_AT_frame_base used for local variables; let's not confuse them further. -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: dwarf2 and frame bases 2004-11-11 19:42 ` Daniel Jacobowitz @ 2004-11-11 22:58 ` Randolph Chung 0 siblings, 0 replies; 9+ messages in thread From: Randolph Chung @ 2004-11-11 22:58 UTC (permalink / raw) To: gdb; +Cc: gdb-patches > Suppose we're in frame A, called from frame B. We're at the first > instruction. If we ask the sentinel frame to unwind the value of r3, > we'll get its real register value - regardless of where we are in the > sequence. If we ask frame A to unwind r3, we want to get frame B's r3. > Where frame A is in its prologue has no effect on what frame B's r3 was > at the time of calling A. ok ok, how about this fix? all the recurse.exp tests pass now. thanks, randolph 2004-11-11 Randolph Chung <tausq@debian.org> * hppa-tdep.c (hppa_frame_cache): Properly handle the frame pointer register so that it can be unwound from anywhere in the prologue. Index: hppa-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/hppa-tdep.c,v retrieving revision 1.177 diff -u -p -r1.177 hppa-tdep.c --- hppa-tdep.c 10 Nov 2004 16:26:55 -0000 1.177 +++ hppa-tdep.c 11 Nov 2004 21:02:42 -0000 @@ -1562,6 +1573,7 @@ hppa_frame_cache (struct frame_info *nex long frame_size; struct unwind_table_entry *u; CORE_ADDR prologue_end; + int fp_in_r1 = 0; int i; if (hppa_debug) @@ -1694,6 +1712,10 @@ hppa_frame_cache (struct frame_info *nex looking_for_sp = 0; cache->saved_regs[HPPA_FP_REGNUM].addr = 0; } + else if (inst == 0x08030241) /* copy %r3, %r1 */ + { + fp_in_r1 = 1; + } /* Account for general and floating-point register saves. */ reg = inst_saves_gr (inst); @@ -1802,9 +1824,6 @@ hppa_frame_cache (struct frame_info *nex and saved on the stack, the Save_SP flag is set. We use this to decide whether to use the frame pointer for unwinding. - fp may be zero if it is not available in an inner frame because - it has been modified by not yet saved. - TODO: For the HP compiler, maybe we should use the alloca_frame flag instead of Save_SP. */ @@ -1867,13 +1886,26 @@ hppa_frame_cache (struct frame_info *nex } } - /* If the frame pointer was not saved in this frame, but we should be saving - it, set it to an invalid value so that another frame will not pick up the - wrong frame pointer. This can happen if we start unwinding after the - frame pointer has been modified, but before we've saved it to the - stack. */ - if (u->Save_SP && !trad_frame_addr_p (cache->saved_regs, HPPA_FP_REGNUM)) - trad_frame_set_value (cache->saved_regs, HPPA_FP_REGNUM, 0); + /* If Save_SP is set, then we expect the frame pointer to be saved in the + frame. However, there is a one-insn window where we haven't saved it + yet, but we've already clobbered it. Detect this case and fix it up. + + The prologue sequence for frame-pointer functions is: + 0: stw %rp, -20(%sp) + 4: copy %r3, %r1 + 8: copy %sp, %r3 + c: stw,ma %r1, XX(%sp) + + So if we are at offset c, the r3 value that we want is not yet saved + on the stack, but it's been overwritten. The prologue analyzer will + set fp_in_r1 when it sees the copy insn so we know to get the value + from r1 instead. */ + if (u->Save_SP && !trad_frame_addr_p (cache->saved_regs, HPPA_FP_REGNUM) + && fp_in_r1) + { + ULONGEST r1 = frame_unwind_register_unsigned (next_frame, 1); + trad_frame_set_value (cache->saved_regs, HPPA_FP_REGNUM, r1); + } { /* Convert all the offsets into addresses. */ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: dwarf2 and frame bases 2004-11-11 17:12 ` Randolph Chung 2004-11-11 19:42 ` Daniel Jacobowitz @ 2004-11-11 19:47 ` Mark Kettenis 2004-11-11 21:18 ` Daniel Jacobowitz 1 sibling, 1 reply; 9+ messages in thread From: Mark Kettenis @ 2004-11-11 19:47 UTC (permalink / raw) To: randolph; +Cc: gdb Date: Thu, 11 Nov 2004 08:48:52 -0800 From: Randolph Chung <randolph@tausq.org> sounds like it should still work (i.e it should still be a valid address), except the hppa targer has an explicit check for when we expect r3 to be modified but we may be in the process of changing it (since it's a 3 insn sequence). In that case, we zero the register to tell the unwinder not to use the value in the r3 to calculate the frame base (it uses the stack pointer and other unwind information in that case) See http://sources.redhat.com/ml/gdb-patches/2004-06/msg00108.html for more details. i know it is kind of hacky, but the frame unwinding code is explicitly asking "what is the frame base of this frame", and the target code is especially tuned for that..... It is certainly hacky, and defenitely wrong. "Thou shallt not lie about your register contents". i see two possible solutions: 1) perhaps the hppa target should use some other mechanism (instead of mucking with r3) to tell the next frame that the frame pointer is not available..... Why does the next frame need that frame pointer? 2) in the dwarf code, when trying to get the frame base, should we explicitly ask for the frame base instead of using the dwarf expression? perhaps this could be something that can be overridden by the target, so that the default still uses the dwarf information. The problem here is that the debug information provided my the compiler is wrong, or at least incomplete. This should be fixed in the compiler, not in GDB. Unfortunately this probably means we need to have proper support for location expressions in GDB. Mark ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: dwarf2 and frame bases 2004-11-11 19:47 ` Mark Kettenis @ 2004-11-11 21:18 ` Daniel Jacobowitz 0 siblings, 0 replies; 9+ messages in thread From: Daniel Jacobowitz @ 2004-11-11 21:18 UTC (permalink / raw) To: Mark Kettenis; +Cc: randolph, gdb On Thu, Nov 11, 2004 at 08:41:40PM +0100, Mark Kettenis wrote: > The problem here is that the debug information provided my the > compiler is wrong, or at least incomplete. This should be fixed in > the compiler, not in GDB. Unfortunately this probably means we need > to have proper support for location expressions in GDB. Is there anything in particular that you know is missing? The only open issue I know of is multiple locations with overapping live ranges. Using a location list for the frame base should work. [But it's not clear how useful making DW_AT_frame_base work from the first instruction of the function is... the locals are all still uninitialized anyway.] -- Daniel Jacobowitz ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-11-11 21:18 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-11-10 23:57 dwarf2 and frame bases Randolph Chung 2004-11-10 23:58 ` Daniel Jacobowitz 2004-11-11 3:09 ` Randolph Chung 2004-11-11 9:57 ` Daniel Jacobowitz 2004-11-11 17:12 ` Randolph Chung 2004-11-11 19:42 ` Daniel Jacobowitz 2004-11-11 22:58 ` Randolph Chung 2004-11-11 19:47 ` Mark Kettenis 2004-11-11 21:18 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox