daily update
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 9d8ab68cfac0559492aa6f08197e0f46329d16a9..06f3ea09dd3f0ad18a5363b48480c1f24837d7f5 100644 (file)
@@ -3,7 +3,7 @@
 
    Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
    1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008, 2009 Free Software Foundation, Inc.
+   2008, 2009, 2010 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -68,8 +68,6 @@ static int hook_stop_stub (void *);
 
 static int restore_selected_frame (void *);
 
-static void build_infrun (void);
-
 static int follow_fork (void);
 
 static void set_schedlock_func (char *args, int from_tty,
@@ -764,7 +762,7 @@ follow_exec (ptid_t pid, char *execd_pathname)
 #ifdef SOLIB_CREATE_INFERIOR_HOOK
   SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
 #else
-  solib_create_inferior_hook ();
+  solib_create_inferior_hook (0);
 #endif
 
   jit_inferior_created_hook ();
@@ -1856,13 +1854,14 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
      or a return command, we often end up a few instructions forward, still 
      within the original line we started.
 
-     An attempt was made to have init_execution_control_state () refresh
-     the prev_pc value before calculating the line number.  This approach
-     did not work because on platforms that use ptrace, the pc register
-     cannot be read unless the inferior is stopped.  At that point, we
-     are not guaranteed the inferior is stopped and so the regcache_read_pc ()
-     call can fail.  Setting the prev_pc value here ensures the value is 
-     updated correctly when the inferior is stopped.  */
+     An attempt was made to refresh the prev_pc at the same time the
+     execution_control_state is initialized (for instance, just before
+     waiting for an inferior event).  But this approach did not work
+     because of platforms that use ptrace, where the pc register cannot
+     be read unless the inferior is stopped.  At that point, we are not
+     guaranteed the inferior is stopped and so the regcache_read_pc() call
+     can fail.  Setting the prev_pc value here ensures the value is updated
+     correctly when the inferior is stopped.  */
   tp->prev_pc = regcache_read_pc (get_current_regcache ());
 
   /* Fill in with reasonable starting values.  */
@@ -1999,8 +1998,6 @@ struct execution_control_state
   int wait_some_more;
 };
 
-static void init_execution_control_state (struct execution_control_state *ecs);
-
 static void handle_inferior_event (struct execution_control_state *ecs);
 
 static void handle_step_into_function (struct gdbarch *gdbarch,
@@ -2403,15 +2400,6 @@ set_step_info (struct frame_info *frame, struct symtab_and_line sal)
   tp->current_line = sal.line;
 }
 
-/* Prepare an execution control state for looping through a
-   wait_for_inferior-type loop.  */
-
-static void
-init_execution_control_state (struct execution_control_state *ecs)
-{
-  ecs->random_signal = 0;
-}
-
 /* Clear context switchable stepping state.  */
 
 void
@@ -2946,7 +2934,11 @@ handle_inferior_event (struct execution_control_state *ecs)
        = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
                              stop_pc, ecs->ptid);
 
-      ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
+      /* Note that we're interested in knowing the bpstat actually
+        causes a stop, not just if it may explain the signal.
+        Software watchpoints, for example, always appear in the
+        bpstat.  */
+      ecs->random_signal = !bpstat_causes_stop (ecs->event_thread->stop_bpstat);
 
       /* If no catchpoint triggered for this, then keep going.  */
       if (ecs->random_signal)
@@ -3004,6 +2996,7 @@ handle_inferior_event (struct execution_control_state *ecs)
        context_switch (ecs->ptid);
 
       current_inferior ()->waiting_for_vfork_done = 0;
+      current_inferior ()->pspace->breakpoints_not_allowed = 0;
       /* This also takes care of reinserting breakpoints in the
         previously locked inferior.  */
       keep_going (ecs);
@@ -3130,6 +3123,9 @@ targets should add new threads to the thread list themselves in non-stop mode.")
     {
       struct regcache *regcache = get_thread_regcache (ecs->ptid);
       struct gdbarch *gdbarch = get_regcache_arch (regcache);
+      struct cleanup *old_chain = save_inferior_ptid ();
+
+      inferior_ptid = ecs->ptid;
 
       fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = %s\n",
                           paddress (gdbarch, stop_pc));
@@ -3146,6 +3142,8 @@ targets should add new threads to the thread list themselves in non-stop mode.")
             fprintf_unfiltered (gdb_stdlog,
                                 "infrun: (no data address available)\n");
        }
+
+      do_cleanups (old_chain);
     }
 
   if (stepping_past_singlestep_breakpoint)
@@ -3222,7 +3220,8 @@ targets should add new threads to the thread list themselves in non-stop mode.")
   if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
     {
       int thread_hop_needed = 0;
-      struct address_space *aspace = get_regcache_aspace (get_current_regcache ());
+      struct address_space *aspace = 
+       get_regcache_aspace (get_thread_regcache (ecs->ptid));
 
       /* Check if a regular breakpoint has been hit before checking
          for a potential single step breakpoint. Otherwise, GDB will
@@ -3583,6 +3582,21 @@ targets should add new threads to the thread list themselves in non-stop mode.")
         function.  */
       stop_print_frame = 1;
 
+      /* This is where we handle "moribund" watchpoints.  Unlike
+        software breakpoints traps, hardware watchpoint traps are
+        always distinguishable from random traps.  If no high-level
+        watchpoint is associated with the reported stop data address
+        anymore, then the bpstat does not explain the signal ---
+        simply make sure to ignore it if `stopped_by_watchpoint' is
+        set.  */
+
+      if (debug_infrun
+         && ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
+         && !bpstat_explains_signal (ecs->event_thread->stop_bpstat)
+         && stopped_by_watchpoint)
+       fprintf_unfiltered (gdb_stdlog, "\
+infrun: no user watchpoint explains watchpoint SIGTRAP, ignoring\n");
+
       /* NOTE: cagney/2003-03-29: These two checks for a random signal
          at one stage in the past included checks for an inferior
          function call's call dummy's return breakpoint.  The original
@@ -3606,6 +3620,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
       if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
        ecs->random_signal
          = !(bpstat_explains_signal (ecs->event_thread->stop_bpstat)
+             || stopped_by_watchpoint
              || ecs->event_thread->trap_expected
              || (ecs->event_thread->step_range_end
                  && ecs->event_thread->step_resume_breakpoint == NULL));
@@ -4039,6 +4054,11 @@ infrun: not switching back to stepped thread, it has vanished\n");
       return;
     }
 
+  /* Re-fetch current thread's frame in case the code above caused
+     the frame cache to be re-initialized, making our FRAME variable
+     a dangling pointer.  */
+  frame = get_current_frame ();
+
   /* If stepping through a line, keep going if still within it.
 
      Note that step_range_end is the address of the first instruction
@@ -4150,7 +4170,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
      "outermost" function.  This could be fixed by marking
      outermost frames as !stack_p,code_p,special_p.  Then the
      initial outermost frame, before sp was valid, would
-     have code_addr == &_start.  See the commend in frame_id_eq
+     have code_addr == &_start.  See the comment in frame_id_eq
      for more.  */
   if (!frame_id_eq (get_stack_frame_id (frame),
                    ecs->event_thread->step_stack_frame_id)
This page took 0.026213 seconds and 4 git commands to generate.