This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: CRIS port; frame cleanup crash
- From: Andrew Cagney <cagney at gnu dot org>
- To: Orjan Friberg <orjan dot friberg at axis dot com>
- Cc: gdb-patches at sources dot redhat dot com,Michael Elizabeth Chastain <mec dot gnu at mindspring dot com>,Joel Brobecker <brobecker at gnat dot com>
- Date: Sat, 14 Feb 2004 09:52:02 -0500
- Subject: Re: CRIS port; frame cleanup crash
- References: <3F392591.4050409@redhat.com> <402BCCF2.601@axis.com> <402BDCDF.5040506@gnu.org> <402E24DC.8060006@axis.com>
[Joel, MichaelC, FYI]
Andrew Cagney wrote:
The term "unwind" is used by the dwarf-2 specification. http://www.eagercon.com/dwarf/dwarf3std.htm
it includes a working example in the appendix.
Excellent, thanks a lot. Section 6.4 regarding Call Frame Information cleared up some of the confusion regarding unwinding.
The important thing is to "dig out" the register from the correct frame. frame_unwind_register (next_frame, "pc") will "dig out" the PC from the next frame (often found in next frame's link register) returning the value as it should be in "this_frame".
This explanation has me slightly puzzled. I gather from the code that "PC" refers to the current program location within a frame, and not an actual CPU register. Is "next" synonymous with "outer" in your explanation above? (Perhaps a stupid question; maybe unwind by definition works on the outer frame/caller.) And "link register" I assume is the equivalent of a subroutine return pointer.
Yes, "pc" is a misnomer, within GDB it doesn't mean the "pc register",
"resume address" is closer. Check the comments in frame.c:struct
frame_info for definitions of: "next", "inner", "newer" and separatly
"prev", "outer", "older". Yes, link register is the return address
register.
This frame (the caller) calls next frame (the callee). As part of that
the callers resume addresses ends up in the callee's return-address
register. The callee (next) then saves the return-address register on
the stack. Hence to get the callers (this) PC, it needs to be dug out
of the callers (next) frame's stack. Anyway, sounds like you've got it
right.
Approaching it from another direction, what would be a good test to see if the unwind code works correctly? At present, step (into function calls), next (over function calls), finish, and backtrace seem to work ok for both leaf- and non-leaf-functions (for CRIS the prologue differs slightly as the SRP isn't pushed in case of a leaf function). Is there any particular existing testcase that would be good at detecting errors in the frame code?
Exactly that.
Also "advance.exp", in particular the sequence:
./gdb advance
(gdb) break func
(gdb) run
(gdb) advance func3
--- should break in main and not func3
is a good check of the frame ID.
And callfuncs.exp, and a sequence like:
./gdb callfuncs
(gdb) break add
(gdb) break main
(gdb) run
(gdb) print add(1,2)
(gdb) bt
(gdb) print add(3,4)
(gdb) bt
add(3,4)
<dummy frame>
add (1,2)
<dummy frame>
main ()
(gdb)
is a good check of dummy frames
Another question: should I hook in the dwarf-2 frame sniffer from the very beginning? Or wait until the other stuff seems to be working ok?
Towards the end. It's good to first get the old code working reasonably
well.
Andrew