]> Git Repo - binutils.git/blobdiff - gdb/infrun.c
Fri Apr 29 14:26:35 1994 Stan Shebs ([email protected])
[binutils.git] / gdb / infrun.c
index 62d4333ff3370cf7f5b60afeaa3388047822f71b..dfe2cc0ae783ac8f14484ab671d260c05bd8987a 100644 (file)
@@ -75,7 +75,7 @@ hook_stop_stub PARAMS ((char *));
 #endif
 
 /* For SVR4 shared libraries, each call goes through a small piece of
-   trampoline code in the ".init" section.  IN_SOLIB_TRAMPOLINE evaluates
+   trampoline code in the ".plt" section.  IN_SOLIB_TRAMPOLINE evaluates
    to nonzero if we are current stopped in one of these. */
 #ifndef IN_SOLIB_TRAMPOLINE
 #define IN_SOLIB_TRAMPOLINE(pc,name)   0
@@ -280,6 +280,15 @@ proceed (addr, siggnal, step)
 
       if (breakpoint_here_p (read_pc ()))
        oneproc = 1;
+
+#ifdef STEP_SKIPS_DELAY
+      /* Check breakpoint_here_p first, because breakpoint_here_p is fast
+        (it just checks internal GDB data structures) and STEP_SKIPS_DELAY
+        is slow (it needs to read memory from the target).  */
+      if (breakpoint_here_p (read_pc () + 4)
+         && STEP_SKIPS_DELAY (read_pc ()))
+       oneproc = 1;
+#endif /* STEP_SKIPS_DELAY */
     }
   else
     write_pc (addr);
@@ -335,6 +344,7 @@ static CORE_ADDR prev_pc;
 static CORE_ADDR prev_sp;
 static CORE_ADDR prev_func_start;
 static char *prev_func_name;
+static CORE_ADDR prev_frame_address;
 
 \f
 /* Start remote-debugging of a machine over a serial link.  */
@@ -360,6 +370,7 @@ init_wait_for_inferior ()
   prev_sp = 0;
   prev_func_start = 0;
   prev_func_name = NULL;
+  prev_frame_address = 0;
 
   trap_expected_after_continue = 0;
   breakpoints_inserted = 0;
@@ -402,20 +413,24 @@ wait_for_inferior ()
   struct symtab *current_symtab;
   int handling_longjmp = 0;    /* FIXME */
   struct breakpoint *step_resume_breakpoint = NULL;
+  struct breakpoint *through_sigtramp_breakpoint = NULL;
   int pid;
 
   old_cleanups = make_cleanup (delete_breakpoint_current_contents,
                               &step_resume_breakpoint);
+  make_cleanup (delete_breakpoint_current_contents,
+               &through_sigtramp_breakpoint);
   sal = find_pc_line(prev_pc, 0);
   current_line = sal.line;
   current_symtab = sal.symtab;
 
   /* Are we stepping?  */
-#define CURRENTLY_STEPPING() ((step_resume_breakpoint == NULL \
-                              && !handling_longjmp \
-                              && (step_range_end \
-                                  || trap_expected)) \
-                             || bpstat_should_step ())
+#define CURRENTLY_STEPPING() \
+  ((through_sigtramp_breakpoint == NULL \
+    && !handling_longjmp \
+    && ((step_range_end && step_resume_breakpoint == NULL) \
+       || trap_expected)) \
+   || bpstat_should_step ())
 
   while (1)
     {
@@ -571,6 +586,15 @@ switch_thread:
                      delete_breakpoint (step_resume_breakpoint);
                      step_resume_breakpoint = NULL;
                    }
+
+                 /* Not sure whether we need to blow this away too,
+                    but probably it is like the step-resume
+                    breakpoint.  */
+                 if (through_sigtramp_breakpoint)
+                   {
+                     delete_breakpoint (through_sigtramp_breakpoint);
+                     through_sigtramp_breakpoint = NULL;
+                   }
                  prev_pc = 0;
                  prev_sp = 0;
                  prev_func_name = NULL;
@@ -600,8 +624,9 @@ switch_thread:
        single_step (0);        /* This actually cleans up the ss */
 #endif /* NO_SINGLE_STEP */
       
-/* If PC is pointing at a nullified instruction, then step beyond it so that
-   the user won't be confused when GDB appears to be ready to execute it. */
+      /* If PC is pointing at a nullified instruction, then step beyond
+        it so that the user won't be confused when GDB appears to be ready
+        to execute it. */
 
       if (INSTRUCTION_NULLIFIED)
        {
@@ -609,7 +634,33 @@ switch_thread:
          continue;
        }
 
-      set_current_frame ( create_new_frame (read_fp (), stop_pc));
+      set_current_frame (create_new_frame (read_fp (), stop_pc));
+      select_frame (get_current_frame (), 0);
+
+#ifdef HAVE_STEPPABLE_WATCHPOINT
+      /* It may not be necessary to disable the watchpoint to stop over
+        it.  For example, the PA can (with some kernel cooperation) 
+        single step over a watchpoint without disabling the watchpoint.  */
+      if (STOPPED_BY_WATCHPOINT (w))
+       {
+         resume (1, 0);
+         continue;
+       }
+#endif
+
+#ifdef HAVE_NONSTEPPABLE_WATCHPOINT
+      /* It is far more common to need to disable a watchpoint
+        to step the inferior over it.  FIXME.  What else might
+        a debug register or page protection watchpoint scheme need
+        here?  */
+      if (STOPPED_BY_WATCHPOINT (w))
+       {
+         remove_breakpoints ();
+         resume (1, 0);
+         insert_breakpoints ();
+         continue;
+       }
+#endif
 
       stop_frame_address = FRAME_FP (get_current_frame ());
       stop_sp = read_sp ();
@@ -663,11 +714,11 @@ switch_thread:
             if just proceeded over a breakpoint.
 
             However, if we are trying to proceed over a breakpoint
-            and end up in sigtramp, then step_resume_breakpoint
+            and end up in sigtramp, then through_sigtramp_breakpoint
             will be set and we should check whether we've hit the
             step breakpoint.  */
          if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected
-             && step_resume_breakpoint == NULL)
+             && through_sigtramp_breakpoint == NULL)
            bpstat_clear (&stop_bpstat);
          else
            {
@@ -786,7 +837,13 @@ switch_thread:
              {
                delete_breakpoint (step_resume_breakpoint);
                step_resume_breakpoint = NULL;
-               what.step_resume = 0;
+             }
+           /* Not sure whether we need to blow this away too, but probably
+              it is like the step-resume breakpoint.  */
+           if (through_sigtramp_breakpoint != NULL)
+             {
+               delete_breakpoint (through_sigtramp_breakpoint);
+               through_sigtramp_breakpoint = NULL;
              }
 
 #if 0
@@ -831,32 +888,42 @@ switch_thread:
 
          case BPSTAT_WHAT_STOP_NOISY:
            stop_print_frame = 1;
-           /* We are about to nuke the step_resume_breakpoint via the
-              cleanup chain, so no need to worry about it here.  */
+
+           /* We are about to nuke the step_resume_breakpoint and
+              through_sigtramp_breakpoint via the cleanup chain, so
+              no need to worry about it here.  */
+
            goto stop_stepping;
 
          case BPSTAT_WHAT_STOP_SILENT:
            stop_print_frame = 0;
-           /* We are about to nuke the step_resume_breakpoint via the
-              cleanup chain, so no need to worry about it here.  */
-           goto stop_stepping;
 
-         case BPSTAT_WHAT_LAST:
-           /* Not a real code, but listed here to shut up gcc -Wall.  */
+           /* We are about to nuke the step_resume_breakpoint and
+              through_sigtramp_breakpoint via the cleanup chain, so
+              no need to worry about it here.  */
 
-         case BPSTAT_WHAT_KEEP_CHECKING:
-           break;
-         }
+           goto stop_stepping;
 
-       if (what.step_resume)
-         {
+         case BPSTAT_WHAT_STEP_RESUME:
            delete_breakpoint (step_resume_breakpoint);
            step_resume_breakpoint = NULL;
+           break;
+
+         case BPSTAT_WHAT_THROUGH_SIGTRAMP:
+           delete_breakpoint (through_sigtramp_breakpoint);
+           through_sigtramp_breakpoint = NULL;
 
            /* If were waiting for a trap, hitting the step_resume_break
               doesn't count as getting it.  */
            if (trap_expected)
              another_trap = 1;
+           break;
+
+         case BPSTAT_WHAT_LAST:
+           /* Not a real code, but listed here to shut up gcc -Wall.  */
+
+         case BPSTAT_WHAT_KEEP_CHECKING:
+           break;
          }
       }
 
@@ -892,10 +959,8 @@ switch_thread:
        /* Having a step-resume breakpoint overrides anything
           else having to do with stepping commands until
           that breakpoint is reached.  */
-       /* I suspect this could/should be keep_going, because if the
-          check_sigtramp2 check succeeds, then it will put in another
-          step_resume_breakpoint, and we aren't (yet) prepared to nest
-          them.  */
+       /* I'm not sure whether this needs to be check_sigtramp2 or
+          whether it could/should be keep_going.  */
        goto check_sigtramp2;
 
       if (step_range_end == 0)
@@ -928,20 +993,29 @@ switch_thread:
       if (IN_SIGTRAMP (stop_pc, stop_func_name)
          && !IN_SIGTRAMP (prev_pc, prev_func_name))
        {
+         /* We've just taken a signal; go until we are back to
+            the point where we took it and one more.  */
+
          /* This code is needed at least in the following case:
             The user types "next" and then a signal arrives (before
             the "next" is done).  */
-         /* We've just taken a signal; go until we are back to
-            the point where we took it and one more.  */
+
+         /* Note that if we are stopped at a breakpoint, then we need
+            the step_resume breakpoint to override any breakpoints at
+            the same location, so that we will still step over the
+            breakpoint even though the signal happened.  */
+
          {
            struct symtab_and_line sr_sal;
 
            sr_sal.pc = prev_pc;
            sr_sal.symtab = NULL;
            sr_sal.line = 0;
+           /* We could probably be setting the frame to
+              prev_frame_address; the reason we don't is that it didn't used
+              to exist.  */
            step_resume_breakpoint =
-             set_momentary_breakpoint (sr_sal, get_current_frame (),
-                                       bp_step_resume);
+             set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
            if (breakpoints_inserted)
              insert_breakpoints ();
          }
@@ -1054,6 +1128,7 @@ step_over_function:
            step_resume_breakpoint =
              set_momentary_breakpoint (sr_sal, get_current_frame (),
                                        bp_step_resume);
+           step_resume_breakpoint->frame = prev_frame_address;
            if (breakpoints_inserted)
              insert_breakpoints ();
          }
@@ -1180,9 +1255,11 @@ step_into_function:
          sr_sal.pc = prev_pc;
          sr_sal.symtab = NULL;
          sr_sal.line = 0;
-         step_resume_breakpoint =
-           set_momentary_breakpoint (sr_sal, get_current_frame (),
-                                     bp_step_resume);
+         /* We perhaps could set the frame if we kept track of what
+            the frame corresponding to prev_pc was.  But we don't,
+            so don't.  */
+         through_sigtramp_breakpoint =
+           set_momentary_breakpoint (sr_sal, NULL, bp_through_sigtramp);
          if (breakpoints_inserted)
            insert_breakpoints ();
 
@@ -1204,6 +1281,7 @@ step_into_function:
                                          function. */
       prev_func_name = stop_func_name;
       prev_sp = stop_sp;
+      prev_frame_address = stop_frame_address;
 
       /* If we did not do break;, it means we should keep
         running the inferior and not return to debugger.  */
@@ -1230,15 +1308,16 @@ step_into_function:
             to one-proceed past a breakpoint.  */
          /* If we've just finished a special step resume and we don't
             want to hit a breakpoint, pull em out.  */
-         if (step_resume_breakpoint == NULL &&
-             remove_breakpoints_on_following_step)
+         if (step_resume_breakpoint == NULL
+             && through_sigtramp_breakpoint == NULL
+             && remove_breakpoints_on_following_step)
            {
              remove_breakpoints_on_following_step = 0;
              remove_breakpoints ();
              breakpoints_inserted = 0;
            }
          else if (!breakpoints_inserted &&
-                  (step_resume_breakpoint != NULL || !another_trap))
+                  (through_sigtramp_breakpoint != NULL || !another_trap))
            {
              breakpoints_failed = insert_breakpoints ();
              if (breakpoints_failed)
@@ -1278,6 +1357,7 @@ step_into_function:
       prev_func_start = stop_func_start;
       prev_func_name = stop_func_name;
       prev_sp = stop_sp;
+      prev_frame_address = stop_frame_address;
     }
   do_cleanups (old_cleanups);
 }
@@ -1351,8 +1431,6 @@ Further execution is probably impossible.\n");
      if we have one.  */
   if (!stop_stack_dummy)
     {
-      select_frame (get_current_frame (), 0);
-
       if (stop_print_frame)
        {
          int source_only;
@@ -1381,6 +1459,10 @@ Further execution is probably impossible.\n");
          POP_FRAME ends with a setting of the current frame, so we
         can use that next. */
       POP_FRAME;
+      /* Set stop_pc to what it was before we called the function.  Can't rely
+        on restore_inferior_status because that only gets called if we don't
+        stop in the called function.  */
+      stop_pc = read_pc();
       select_frame (get_current_frame (), 0);
     }
 }
@@ -1656,7 +1738,10 @@ signals_info (signum_exp, from_tty)
     }
 
   printf_filtered ("\n");
-  for (oursig = 0; oursig < TARGET_SIGNAL_LAST; ++oursig)
+  /* These ugly casts brought to you by the native VAX compiler.  */
+  for (oursig = TARGET_SIGNAL_FIRST;
+       (int)oursig < (int)TARGET_SIGNAL_LAST;
+       oursig = (enum target_signal)((int)oursig + 1))
     {
       QUIT;
 
This page took 0.036852 seconds and 4 git commands to generate.