This is the mail archive of the gdb-patches@sourceware.org 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: 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)
 {

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