There was a regression by: Re: [rfc, v3] Fix frame_id_inner comparison false positives http://sourceware.org/ml/gdb-patches/2008-08/msg00578.html http://sourceware.org/ml/gdb-cvs/2008-08/msg00182.html 916dde5d38b45a659514e47942ece70aec04cd78 the part: * stack.c (return_command): Directly pop the selected frame. Reproducible on: hp-diablo-01.rhts.eng.bos.redhat.com RHEL5.5-Server-20100216.nightly kernel-2.6.18-187.el5.ia64 Not reproducible on: hp-bl860c-03.rhts.eng.bos.redhat.com RHEL-4.8 kernel-2.6.9-89.EL.ia64 To make ia64-tdep.c compilable +/- this stack.c check-in one must apply: Re: [RFC] Remove addr, endaddr, offset from obj_section http://sourceware.org/ml/gdb-patches/2008-09/msg00011.html http://sourceware.org/ml/gdb-cvs/2008-09/msg00009.html 99072369ec3c8f94c9a596e5ce30bf1f1c4bf20e It is reproducible by: gdb.base/call-signal-resume.exp although one must first remove the gdb_assert by: gdb-infcall-sp-underflow.patch Reproducer: set confirm no set breakpoint pending on set height 0 set width 0 # testcase from: gdb-6.8-37.el5.src file gdb.base/call-signals break stop_one run call gen_signal () bt frame 3 return p/x $sp break stop_two info break p/x $pc p/x $sp bt set debug infrun 1 delete 1 continue bt p/x $pc echo Bug is reproduced if sp is now 0:\n p/x $sp kill quit --- ./gdb/frame.c 2010-02-23 21:35:35.000000000 +0100 +++ ./gdb/frame.c 2010-02-23 21:46:34.000000000 +0100 @@ -517,7 +517,7 @@ frame_id_eq (struct frame_id l, struct f a stack overflow strategy that cause the handler to be run on a different stack. */ -static int +int frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, struct frame_id r) { int inner; --- ./gdb/frame.h 2009-09-13 18:28:28.000000000 +0200 +++ ./gdb/frame.h 2010-02-23 21:46:10.000000000 +0100 @@ -708,4 +708,7 @@ extern struct frame_info *create_new_fra extern int frame_unwinder_is (struct frame_info *fi, const struct frame_unwind *unwinder); +extern int frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, + struct frame_id r); + #endif /* !defined (FRAME_H) */ --- ./gdb/stack.c 2010-02-23 21:35:34.000000000 +0100 +++ ./gdb/stack.c 2010-02-23 21:44:39.000000000 +0100 @@ -1967,8 +1967,29 @@ If you continue, the return value that y error (_("Not confirmed")); } - /* Discard the selected frame and all frames inner-to it. */ - frame_pop (get_selected_frame (NULL)); + /* NOTE: cagney/2003-01-18: Is this silly? Rather than pop each + frame in turn, should this code just go straight to the relevant + frame and pop that? */ + + /* First discard all frames inner-to the selected frame (making the + selected frame current). */ + { + struct frame_id selected_id = get_frame_id (get_selected_frame (NULL)); + while (!frame_id_eq (selected_id, get_frame_id (get_current_frame ()))) + { + struct frame_info *frame = get_current_frame (); + if (frame_id_inner (get_frame_arch (frame), selected_id, + get_frame_id (frame))) + /* Caught in the safety net, oops! We've gone way past the + selected frame. */ + error (_("Problem while popping stack frames (corrupt stack?)")); + frame_pop (get_current_frame ()); + } + } + + /* Second discard the selected frame (which is now also the current + frame). */ + frame_pop (get_current_frame ()); /* Store RETURN_VALUE in the just-returned register set. */ if (return_value != NULL)