This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: Fix for PR 1971 .
Hi Jim,
> > > Attached is a fix for PR 1971. This inserts a breakpoint at the return
> > > address for a function that does not have a previous frame which is what
> > > you have in the case of main. This would however not stop after the
> > > return from main because the semantics of the next command would not
> > > stop the execution in any place where there is no debug information.
> > >
> > > Tested on native x86 with today's head as well as 6.4 branch with no
> > > extra regressions .
> >
> > Is this the behavior we actually want? Where the user hasn't "set
> > backtrace past-main on", isn't it the correct behavior for GDB to
> > allow the program to exit when doing a 'next' out of main? (I assume
> > that, if one does a 'set backtrace past-main on', then 'next' works as
> > you suggest it should.)
>
> Oh, wait. I might understand better now. The current behavior is a
> segfault, as get_prev_frame returns NULL. The code you patched is
> clearly wrong as it stands, since it doesn't account for that
> possibility. The behavior with your patch is that 'next' from main
> causes the program to run to completion when past-main is off, as I
> suggested it ought. Right?
Right . Thats the intended behaviour. The debuggee would run to
completion depending on whether there exists debug info beyond main or
not.
> I see three uses of insert_step_resume_breakpoint_at_frame
> (get_prev_frame (get_current_frame ())) in infrun.c; would it be
> reasonable to add a new function in the
> insert_step_resume_breakpoint_at_* family,
> insert_step_resume_breakpoint_at_caller (say), that sets the
> step-resume breakpoint at a sal built from the given frame's return
> address?
>
> I think you'd want to use frame_pc_unwind in that function, and not
> gdbarch_unwind_pc.
>
Here's an updated patch that uses a new function
insert_step_resume_breakpoint_at_caller and frame_pc_unwind as suggested
which has been tested on x86-linux with an extra pass in
watchthreads.exp, I am still not sure why this gets fixed by this..
Ok to commit ?
2006-01-04 Ramana Radhakrishnan <ramana.radhakrishnan@codito.com>
PR 1971
* infrun.c (insert_step_resume_breakpoint_at_caller):New
function.
(handle_inferior_event):Use above.
cheers
Ramana
--
Ramana Radhakrishnan
GNU Tools
codito ergo sum (www.codito.com)
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.208
diff -u -a -u -r1.208 infrun.c
--- infrun.c 17 Dec 2005 22:34:01 -0000 1.208
+++ infrun.c 4 Jan 2006 04:40:11 -0000
@@ -943,6 +943,7 @@
static void step_into_function (struct execution_control_state *ecs);
static void insert_step_resume_breakpoint_at_frame (struct frame_info *step_frame);
+static void insert_step_resume_breakpoint_at_caller (struct frame_info *step_frame);
static void insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
struct frame_id sr_id);
static void stop_stepping (struct execution_control_state *ecs);
@@ -2390,7 +2391,8 @@
/* We're doing a "next", set a breakpoint at callee's return
address (the address at which the caller will
resume). */
- insert_step_resume_breakpoint_at_frame (get_prev_frame (get_current_frame ()));
+
+ insert_step_resume_breakpoint_at_caller ( get_current_frame ());
keep_going (ecs);
return;
}
@@ -2453,7 +2455,7 @@
/* Set a breakpoint at callee's return address (the address at
which the caller will resume). */
- insert_step_resume_breakpoint_at_frame (get_prev_frame (get_current_frame ()));
+ insert_step_resume_breakpoint_at_caller ( get_current_frame ());
keep_going (ecs);
return;
}
@@ -2522,7 +2524,7 @@
{
/* Set a breakpoint at callee's return address (the address
at which the caller will resume). */
- insert_step_resume_breakpoint_at_frame (get_prev_frame (get_current_frame ()));
+ insert_step_resume_breakpoint_at_caller ( get_current_frame ());
keep_going (ecs);
return;
}
@@ -2757,6 +2759,30 @@
insert_step_resume_breakpoint_at_sal (sr_sal, get_frame_id (return_frame));
}
+/* Insert a step resume breakpoint at the return address of the
+ caller. This is to ensure that on doing a next from before main completes
+ execution of the program without GDB dumping core. Look at PR 1971
+ for more details. */
+
+static void
+insert_step_resume_breakpoint_at_caller (struct frame_info *return_frame)
+{
+ if (get_prev_frame (return_frame))
+ {
+ insert_step_resume_breakpoint_at_frame (get_prev_frame (return_frame));
+ }
+ else
+ {
+ struct symtab_and_line sr_sal;
+ init_sal (&sr_sal); /* initialize to zeros */
+ sr_sal.pc = ADDR_BITS_REMOVE (frame_pc_unwind (return_frame));
+ sr_sal.section = find_pc_overlay (sr_sal.pc);
+ insert_step_resume_breakpoint_at_sal (sr_sal, null_frame_id);
+ }
+
+}
+
+
static void
stop_stepping (struct execution_control_state *ecs)
{