Thu Jul 25 12:08:09 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 19ff2d3dd66e374f76083ca1efed2b8100704047..0089b7ef7859c669c3f7d99d265703179f572e10 100644 (file)
@@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "gdbcore.h"
 #include "gdbcmd.h"
 #include "target.h"
-#include "thread.h"
+#include "gdbthread.h"
 #include "annotate.h"
 
 #include <signal.h>
@@ -200,6 +200,8 @@ extern int one_stepped;             /* From machine dependent code */
 extern void single_step ();    /* Same. */
 #endif /* NO_SINGLE_STEP */
 
+extern void write_pc_pid PARAMS ((CORE_ADDR, int));
+
 \f
 /* Things to clean up if we QUIT out of resume ().  */
 /* ARGSUSED */
@@ -457,7 +459,10 @@ wait_for_inferior ()
   CORE_ADDR stop_func_start;
   CORE_ADDR stop_func_end;
   char *stop_func_name;
-  CORE_ADDR prologue_pc = 0, tmp;
+#if 0
+  CORE_ADDR prologue_pc = 0;
+#endif
+  CORE_ADDR tmp;
   struct symtab_and_line sal;
   int remove_breakpoints_on_following_step = 0;
   int current_line;
@@ -498,9 +503,12 @@ wait_for_inferior ()
       else
        pid = target_wait (-1, &w);
 
-#ifdef HAVE_NONSTEPPABLE_WATCHPOINT
+    /* Gross.
+
+       We goto this label from elsewhere in wait_for_inferior when we want
+       to continue the main loop without calling "wait" and trashing the
+       waitstatus contained in W.  */
     have_waited:
-#endif
 
       flush_cached_frames ();
 
@@ -606,31 +614,38 @@ wait_for_inferior ()
         another thread.  If so, then step that thread past the breakpoint,
         and continue it.  */
 
-      if (stop_signal == TARGET_SIGNAL_TRAP
-         && breakpoints_inserted
-         && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
+      if (stop_signal == TARGET_SIGNAL_TRAP)
        {
-         random_signal = 0;
-         if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, pid))
-           {
-             /* Saw a breakpoint, but it was hit by the wrong thread.  Just continue. */
-             write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, pid);
+#ifdef NO_SINGLE_STEP
+         if (one_stepped)
+           random_signal = 0;
+         else
+#endif
+           if (breakpoints_inserted
+               && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK))
+             {
+               random_signal = 0;
+               if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, pid))
+                 {
+                   /* Saw a breakpoint, but it was hit by the wrong thread.  Just continue. */
+                   write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, pid);
 
-             remove_breakpoints ();
-             target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
-             /* FIXME: What if a signal arrives instead of the single-step
-                happening?  */
+                   remove_breakpoints ();
+                   target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */
+                   /* FIXME: What if a signal arrives instead of the single-step
+                      happening?  */
 
-             if (target_wait_hook)
-               target_wait_hook (pid, &w);
-             else
-               target_wait (pid, &w);
-             insert_breakpoints ();
+                   if (target_wait_hook)
+                     target_wait_hook (pid, &w);
+                   else
+                     target_wait (pid, &w);
+                   insert_breakpoints ();
 
-             /* We need to restart all the threads now.  */
-             target_resume (-1, 0, TARGET_SIGNAL_0);
-             continue;
-           }
+                   /* We need to restart all the threads now.  */
+                   target_resume (-1, 0, TARGET_SIGNAL_0);
+                   continue;
+                 }
+             }
        }
       else
        random_signal = 1;
@@ -712,8 +727,22 @@ wait_for_inferior ()
 
       if (INSTRUCTION_NULLIFIED)
        {
-         resume (1, 0);
-         continue;
+         struct target_waitstatus tmpstatus;
+
+         registers_changed ();
+         target_resume (pid, 1, TARGET_SIGNAL_0);
+
+         /* We may have received a signal that we want to pass to
+            the inferior; therefore, we must not clobber the waitstatus
+            in W.  So we call wait ourselves, then continue the loop
+            at the "have_waited" label.  */
+         if (target_wait_hook)
+           target_wait_hook (pid, &tmpstatus);
+         else
+           target_wait (pid, &tmpstatus);
+
+
+         goto have_waited;
        }
 
 #ifdef HAVE_STEPPABLE_WATCHPOINT
@@ -1039,10 +1068,24 @@ wait_for_inferior ()
            {
              extern int auto_solib_add;
 
+             /* Remove breakpoints, we eventually want to step over the
+                shlib event breakpoint, and SOLIB_ADD might adjust
+                breakpoint addresses via breakpoint_re_set.  */
+             if (breakpoints_inserted)
+               remove_breakpoints ();
+             breakpoints_inserted = 0;
+
              /* Check for any newly added shared libraries if we're
                 supposed to be adding them automatically.  */
              if (auto_solib_add)
-               SOLIB_ADD (NULL, 0, NULL);
+               {
+                 /* Switch terminal for any messages produced by
+                    breakpoint_re_set.  */
+                 target_terminal_ours_for_output ();
+                 SOLIB_ADD (NULL, 0, NULL);
+                 re_enable_breakpoints_in_shlibs ();
+                 target_terminal_inferior ();
+               }
 
              /* If requested, stop when the dynamic linker notifies
                 gdb of events.  This allows the user to get control
@@ -1057,7 +1100,6 @@ wait_for_inferior ()
                {
                  /* We want to step over this breakpoint, then keep going.  */
                  another_trap = 1;
-                 remove_breakpoints_on_following_step = 1;
                  break;
                }
            }
@@ -1658,7 +1700,9 @@ Further execution is probably impossible.\n");
 
   target_terminal_ours ();
 
-  if (stop_bpstat && stop_bpstat->breakpoint_at->type == bp_shlib_event)
+  if (stop_bpstat
+      && stop_bpstat->breakpoint_at
+      && stop_bpstat->breakpoint_at->type == bp_shlib_event)
     printf_filtered ("Stopped due to shared library event\n");
 
   /* Look up the hook_stop and run it if it exists.  */
This page took 0.025746 seconds and 4 git commands to generate.