This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: CRIS port; frame cleanup crash


[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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]