* breakpoint.h (enum bptype): New type bp_through_sigtramp.
authorJim Kingdon <jkingdon@engr.sgi.com>
Fri, 25 Feb 1994 09:12:29 +0000 (09:12 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Fri, 25 Feb 1994 09:12:29 +0000 (09:12 +0000)
(bpstat_what_main_action): New code BPSTAT_WHAT_THROUGH_SIGTRAMP.
* breakpoint.c (bpstat_what): Return BPSTAT_WHAT_THROUGH_SIGTRAMP
if we hit a bp_through_sigtramp breakpoint.  Remove kludge which
ignored bs->stop for a bp_step_resume breakpoint.
* infrun.c (wait_for_inferior): Make a through_sigtramp_breakpoint
which performs one (the check_sigtramp2 one) of the functions
which had been handled by the step_resume_breakpoint.  For each
use of the step_resume_breakpoint, make it still use the
step_resume_breakpoint, use the through_sigtramp_breakpoint, or
operate on both.
Deal with BPSTAT_WHAT_THROUGH_SIGTRAMP return from bpstat_what.
When setting the frame address of the step resume breakpoint, set
it to the address for frame *before* the call instruction is
executed, not after.

gdb/ChangeLog
gdb/breakpoint.c
gdb/breakpoint.h
gdb/infrun.c

index eea0215..35a3961 100644 (file)
@@ -1,5 +1,21 @@
 Thu Feb 24 08:30:33 1994  Jim Kingdon  (kingdon@deneb.cygnus.com)
 
+       * breakpoint.h (enum bptype): New type bp_through_sigtramp.
+       (bpstat_what_main_action): New code BPSTAT_WHAT_THROUGH_SIGTRAMP.
+       * breakpoint.c (bpstat_what): Return BPSTAT_WHAT_THROUGH_SIGTRAMP
+       if we hit a bp_through_sigtramp breakpoint.  Remove kludge which
+       ignored bs->stop for a bp_step_resume breakpoint.
+       * infrun.c (wait_for_inferior): Make a through_sigtramp_breakpoint
+       which performs one (the check_sigtramp2 one) of the functions
+       which had been handled by the step_resume_breakpoint.  For each
+       use of the step_resume_breakpoint, make it still use the
+       step_resume_breakpoint, use the through_sigtramp_breakpoint, or
+       operate on both.
+       Deal with BPSTAT_WHAT_THROUGH_SIGTRAMP return from bpstat_what.
+       When setting the frame address of the step resume breakpoint, set
+       it to the address for frame *before* the call instruction is
+       executed, not after.
+
        * mips-tdep.c (mips_print_register): Print integers using
        print_scalar_formatted rather than duplicating all the
        CC_HAS_LONG_LONG and so on.
index 717335f..93597d4 100644 (file)
@@ -1267,6 +1267,9 @@ bpstat_what (bs)
     /* We hit the step_resume breakpoint.  */
     step_resume,
 
+    /* We hit the through_sigtramp breakpoint.  */
+    through_sig,
+
     /* This is just used to count how many enums there are.  */
     class_last
     };
@@ -1282,6 +1285,7 @@ bpstat_what (bs)
 #define clrlr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME
 #define clrlrs BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE
 #define sr BPSTAT_WHAT_STEP_RESUME
+#define ts BPSTAT_WHAT_THROUGH_SIGTRAMP
 
 /* "Can't happen."  Might want to print an error message.
    abort() is not out of the question, but chances are GDB is just
@@ -1299,22 +1303,25 @@ bpstat_what (bs)
   /* step_resume entries: a step resume breakpoint overrides another
      breakpoint of signal handling (see comment in wait_for_inferior
      at first IN_SIGTRAMP where we set the step_resume breakpoint).  */
+  /* We handle the through_sigtramp_breakpoint the same way; having both
+     one of those and a step_resume_breakpoint is probably very rare (?).  */
 
   static const enum bpstat_what_main_action
     table[(int)class_last][(int)BPSTAT_WHAT_LAST] =
       {
        /*                              old action */
-       /*       keep_c  stop_s  stop_n  single  setlr   clrlr   clrlrs  sr */
-
-/*no_effect*/  {keep_c, stop_s, stop_n, single, setlr , clrlr , clrlrs, sr},
-/*wp_silent*/  {stop_s, stop_s, stop_n, stop_s, stop_s, stop_s, stop_s, sr},
-/*wp_noisy*/    {stop_n, stop_n, stop_n, stop_n, stop_n, stop_n, stop_n, sr},
-/*bp_nostop*/  {single, stop_s, stop_n, single, setlr , clrlrs, clrlrs, sr},
-/*bp_silent*/  {stop_s, stop_s, stop_n, stop_s, stop_s, stop_s, stop_s, sr},
-/*bp_noisy*/    {stop_n, stop_n, stop_n, stop_n, stop_n, stop_n, stop_n, sr},
-/*long_jump*/  {setlr , stop_s, stop_n, setlr , err   , err   , err   , sr},
-/*long_resume*/        {clrlr , stop_s, stop_n, clrlrs, err   , err   , err   , sr},
-/*step_resume*/        {sr    , sr    , sr    , sr    , sr    , sr    , sr    , sr}
+       /*       keep_c stop_s stop_n single  setlr   clrlr   clrlrs  sr  ts
+        */
+/*no_effect*/  {keep_c,stop_s,stop_n,single, setlr , clrlr , clrlrs, sr, ts},
+/*wp_silent*/  {stop_s,stop_s,stop_n,stop_s, stop_s, stop_s, stop_s, sr, ts},
+/*wp_noisy*/    {stop_n,stop_n,stop_n,stop_n, stop_n, stop_n, stop_n, sr, ts},
+/*bp_nostop*/  {single,stop_s,stop_n,single, setlr , clrlrs, clrlrs, sr, ts},
+/*bp_silent*/  {stop_s,stop_s,stop_n,stop_s, stop_s, stop_s, stop_s, sr, ts},
+/*bp_noisy*/    {stop_n,stop_n,stop_n,stop_n, stop_n, stop_n, stop_n, sr, ts},
+/*long_jump*/  {setlr ,stop_s,stop_n,setlr , err   , err   , err   , sr, ts},
+/*long_resume*/        {clrlr ,stop_s,stop_n,clrlrs, err   , err   , err   , sr, ts},
+/*step_resume*/        {sr    ,sr    ,sr    ,sr    , sr    , sr    , sr    , sr, ts},
+/*through_sig*/ {ts    ,ts    ,ts    ,ts    , ts    , ts    , ts    , ts, ts}
              };
 #undef keep_c
 #undef stop_s
@@ -1324,6 +1331,8 @@ bpstat_what (bs)
 #undef clrlr
 #undef clrlrs
 #undef err
+#undef sr
+#undef ts
   enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
   struct bpstat_what retval;
 
@@ -1370,21 +1379,16 @@ bpstat_what (bs)
          bs_class = long_resume;
          break;
        case bp_step_resume:
-#if 0
-         /* Need to temporarily disable this until we can fix the bug
-            with nexting over a breakpoint with ->stop clear causing
-            an infinite loop.  For now, treat the breakpoint as having
-            been hit even if the frame is wrong.  */
          if (bs->stop)
            {
-#endif
              bs_class = step_resume;
-#if 0
            }
          else
            /* It is for the wrong frame.  */
            bs_class = bp_nostop;
-#endif
+         break;
+       case bp_through_sigtramp:
+         bs_class = through_sig;
          break;
        case bp_call_dummy:
          /* Make sure the action is stop (silent or noisy), so infrun.c
@@ -1468,6 +1472,7 @@ breakpoint_1 (bnum, allflag)
          case bp_longjmp:
          case bp_longjmp_resume:
          case bp_step_resume:
+         case bp_through_sigtramp:
          case bp_call_dummy:
            if (addressprint)
              printf_filtered ("%s ", local_hex_string_custom ((unsigned long) b->address, "08l"));
@@ -1498,6 +1503,7 @@ breakpoint_1 (bnum, allflag)
            printf_filtered ("\tstop only in stack frame at ");
            print_address_numeric (b->frame, gdb_stdout);
            printf_filtered ("\n");
+         }
        if (b->cond)
          {
            printf_filtered ("\tstop only if ");
@@ -1824,7 +1830,7 @@ mention (b)
       break;
     case bp_breakpoint:
       printf_filtered ("Breakpoint %d at ", b->number);
-      print_address_numeric (b->address);
+      print_address_numeric (b->address, gdb_stdout);
       if (b->source_file)
        printf_filtered (": file %s, line %d.",
                         b->source_file, b->line_number);
@@ -1834,6 +1840,7 @@ mention (b)
     case bp_longjmp:
     case bp_longjmp_resume:
     case bp_step_resume:
+    case bp_through_sigtramp:
     case bp_call_dummy:
       break;
     }
index 2bebe3e..5f45ccd 100644 (file)
@@ -49,6 +49,9 @@ enum bptype {
      stepping over signal handlers, and for skipping prologues.  */
   bp_step_resume,
 
+  /* Used by wait_for_inferior for stepping over signal handlers.  */
+  bp_through_sigtramp,
+
   /* The breakpoint at the end of a call dummy.  */
   /* FIXME: What if the function we are calling longjmp()s out of the
      call, or the user gets out with the "return" command?  We currently
@@ -145,6 +148,8 @@ struct breakpoint
   struct block *exp_valid_block;
   /* Value of the watchpoint the last time we checked it.  */
   value val;
+  /* Thread number for thread-specific breakpoint, or -1 if don't care */
+  int thread;
 };
 \f
 /* The following stuff is an abstract data type "bpstat" ("breakpoint status").
@@ -205,23 +210,25 @@ enum bpstat_what_main_action {
   /* Clear longjmp_resume breakpoint, then handle as BPSTAT_WHAT_SINGLE.  */
   BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE,
 
+  /* Clear step resume breakpoint, and keep checking.  */
+  BPSTAT_WHAT_STEP_RESUME,
+
+  /* Clear through_sigtramp breakpoint, muck with trap_expected, and keep
+     checking.  */
+  BPSTAT_WHAT_THROUGH_SIGTRAMP,
+
   /* This is just used to keep track of how many enums there are.  */
   BPSTAT_WHAT_LAST
 };
 
 struct bpstat_what {
-  enum bpstat_what_main_action main_action : 4;
-
-  /* Did we hit the step resume breakpoint?  This is separate from the
-     main_action to allow for it to be combined with any of the main
-     actions.  */
-  unsigned int step_resume : 1;
+  enum bpstat_what_main_action main_action;
 
   /* Did we hit a call dummy breakpoint?  This only goes with a main_action
      of BPSTAT_WHAT_STOP_SILENT or BPSTAT_WHAT_STOP_NOISY (the concept of
      continuing from a call dummy without popping the frame is not a
      useful one).  */
-  unsigned int call_dummy : 1;
+  int call_dummy;
 };
 
 /* Tell what to do about this bpstat.  */
@@ -292,8 +299,11 @@ struct bpstat
 struct frame_info;
 #endif
 
-extern int
-breakpoint_here_p PARAMS ((CORE_ADDR));
+extern int breakpoint_here_p PARAMS ((CORE_ADDR));
+
+extern int frame_in_dummy PARAMS ((struct frame_info *));
+
+extern int breakpoint_thread_match PARAMS ((CORE_ADDR, int));
 
 extern void
 until_break_command PARAMS ((char *, int));
index 9549bce..ef9b826 100644 (file)
@@ -335,6 +335,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 +361,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 +404,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 +577,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;
@@ -663,11 +678,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 +801,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 +852,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 +923,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 +957,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 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.  */
            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 +1092,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 +1219,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 +1245,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.  */
@@ -1238,7 +1280,7 @@ step_into_function:
              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 +1320,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);
 }