This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch] infcall: Remove gdb_assert ($sp underflow)
On Fri, 26 Feb 2010 23:45:10 +0100, Tom Tromey wrote:
> >>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:
>
> Jan> set $sp=0
> Jan> call something()
[...]
> do people really do this sort of thing? Or is this a reduced case of some
> other scenario that actually does happen?
$sp=0 is a perfectly valid 16bit embedded device initialization with ROM 0..16KB
and RAM 16KB..64KB address range with normal PUSH as *--$sp (and POP as *sp++).
But it is true I have met this case as a consequence of a different problem.
Assuming it is a bug in the ia64 part of the subsystem in Linux kernel for
ptrace emulated on top of utrace (that is RHEL-5, such as RHEL-5.4).
Reproducer instructions:
http://cvs.fedoraproject.org/viewvc/rpms/gdb/F-12/gdb-ia64-infcall-workaround.patch?content-type=text%2Fplain&view=co
FYI the ia64 kernel may lock up while dealing with this reproducer.
After an inferior call and some commands inferior $sp gets read by ptrace as 0.
The problem happens since arch-independent change:
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
specifically its last part:
* stack.c (return_command): Directly pop the selected frame.
which is at the bottom of this mail.
I have not found there a bug in this GDB change. The problem is also not
reproducible on ia64 RHEL-4 (RHEL-4.8) which uses non-utrace legacy ptrace
implementation in its Linux kernel.
Thanks,
Jan
--- src/gdb/stack.c 2008/08/21 18:14:39 1.176
+++ src/gdb/stack.c 2008/08/26 17:40:25 1.177
@@ -1844,29 +1844,8 @@
error (_("Not confirmed"));
}
- /* 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 ());
+ /* Discard the selected frame and all frames inner-to it. */
+ frame_pop (get_selected_frame (NULL));
/* Store RETURN_VALUE in the just-returned register set. */
if (return_value != NULL)