On Wednesday 05 December 2007 04:17:52 Jim Blandy wrote: > > Vladimir Prus writes: > > The infrun.c file has a variable named trap_expected, which > > is a bit misleading -- after all, most times when we resume > > inferior, we get SIGTRAP. As it turns out, that variable > > is set when we're stepping over breakpoints, so a better > > name would be stepping_over_breakpoint. Likewise, > > ecs->another_trap also indicates that keep_going should > > be stepping over breakpoint. The attached patch clarifies > > the naming and adds comments, and has no behaviour changes. > > (The patch is on top of my previous breakpoints_inserted > > removing patch). > > OK? ... > So, my suggestions were: > > - We should replace stepping_past_breakpoint and > stepping_past_breakpoint_ptid with a single ptid_t variable, > deferred_step_ptid. > > - We should rename trap_expected to stepped_over_breakpoint. The past > tense 'stepped' suggests that we're talking about a step which has > already happened (which is true by the time we reach > handle_inferior_event). > > (And if I meditate carefully enough on the best possible names, it'll > be quite some time before I have to look at Vlad's harder patches. :)) Here's the patch that renamed stepping_past_breakpoint_ptid. I attach both patch and the delta relative to the previous revision. The 'stepped' vs. 'stepping' change was not done -- for reason I've posted already. OK? - Volodya        * infrun.c (trap_expected): Rename         to stepping_over_breakpoint.  Document.         (stepping_past_breakpoint): Remove.         (stepping_past_breakpoint_ptdi): Renamed         to deferred_step_ptid.         (struct execution_control_state): Rename         the another_trap field to stepping_over_breakpoint.         (struct inferior_status): Rename the trap_expected         field to stepping_over_breakpoint.         (clear_proceed_status, proceed)         (init_execution_control_state, context_switch)         (handle_inferior_event, currently_stepping)         (keep_going, save_inferior_status)         (restore_inferior_status, prepare_to_proceed): Adjust.         * gdbthread.h (struct thread_info): Rename the         trap_expected field to stepping_over_breakpoint.         * thread.c (load_infrun_state, save_infrun_state):         Adjust. ---  gdb/gdbthread.h |    2 +-  gdb/infrun.c    |  117 ++++++++++++++++++++++++++++++++++---------------------  gdb/thread.c    |    8 ++--  3 files changed, 77 insertions(+), 50 deletions(-) diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h index aeb4a40..12e0bcc 100644 --- a/gdb/gdbthread.h +++ b/gdb/gdbthread.h @@ -49,7 +49,7 @@ struct thread_info    struct symtab *current_symtab;    int trap_expected;    int handling_longjmp; -  int another_trap; +  int stepping_over_breakpoint;      /* This is set TRUE when a catchpoint of a shared library event       triggers.  Since we don't wish to leave the inferior in the diff --git a/gdb/infrun.c b/gdb/infrun.c index c608f72..77623b6 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -218,9 +218,30 @@ static struct cmd_list_element *stop_command;    static struct symbol *step_start_function;   -/* Nonzero if we are expecting a trace trap and should proceed from it.  */ +/* Nonzero if we are presenting stepping over breakpoint.   -static int trap_expected; +   If we hit a breakpoint or watchpoint, and then continue, +   we need to single step the current thread with breakpoints +   disabled, so that to avoid hitting the same breakpoint or +   watchpoint again.  And we should step just a single +   thread and keep other threads stopped, so that +   other threads don't miss breakpoints while they are removed. + +   So, this variable simultaneously means that we need to single +   step current thread, keep other threads stopped, and that +   breakpoints should be removed while we step. + +   This variable is set either: +   - in proceed, when we resume inferior on explicit user's request +   - in keep_going, if handle_inferior_event decides we need to +   step over breakpoint.   + +   The variable is cleared in clear_proceed_status, called every +   time before we call proceed.  The proceed calls wait_for_inferior, +   which calls handle_inferior_event in a loop, and until +   wait_for_inferior exits, this variable is changed only by keep_going.  */ + +static int stepping_over_breakpoint;    /* Nonzero if we want to give control to the user when we're notified     of shared library events by the dynamic linker.  */ @@ -442,10 +463,14 @@ static CORE_ADDR singlestep_pc;  static ptid_t saved_singlestep_ptid;  static int stepping_past_singlestep_breakpoint;   -/* Similarly, if we are stepping another thread past a breakpoint, -   save the original thread here so that we can resume stepping it later.  */ -static ptid_t stepping_past_breakpoint_ptid; -static int stepping_past_breakpoint; +/* If not equal to null_ptid, means that after stepping over breakpoint +   is finished, we need to switch to deferred_step_ptid, and step it. + +   The use case is when a breakpoint in one thread, and then the user +   has switched to another thread and issued 'step'. We need to step over +   breakpoint in the thread which hit breakpoint, but then continue +   stepping the thread user has selected.  */ +static ptid_t deferred_step_ptid;      /* Things to clean up if we QUIT out of resume ().  */ @@ -647,7 +672,7 @@ a command like `return' or `jump' to continue execution."));  void  clear_proceed_status (void)  { -  trap_expected = 0; +  stepping_over_breakpoint = 0;    step_range_start = 0;    step_range_end = 0;    step_frame_id = null_frame_id; @@ -693,8 +718,7 @@ prepare_to_proceed (int step)        /* If stepping, remember current thread to switch back to.  */        if (step)         { -         stepping_past_breakpoint = 1; -         stepping_past_breakpoint_ptid = inferior_ptid; +         deferred_step_ptid = inferior_ptid;         }          /* Switch back to WAIT_PID thread.  */ @@ -778,7 +802,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)    if (oneproc)      /* We will get a trace trap after one instruction.         Continue it automatically and insert breakpoints then.  */ -    trap_expected = 1; +    stepping_over_breakpoint = 1;    else      insert_breakpoints ();   @@ -842,7 +866,7 @@ start_remote (int from_tty)    init_thread_list ();    init_wait_for_inferior ();    stop_soon = STOP_QUIETLY_REMOTE; -  trap_expected = 0; +  stepping_over_breakpoint = 0;      /* Always go on waiting for the target, regardless of the mode. */    /* FIXME: cagney/1999-09-23: At present it isn't possible to @@ -887,7 +911,7 @@ init_wait_for_inferior (void)    clear_proceed_status ();      stepping_past_singlestep_breakpoint = 0; -  stepping_past_breakpoint = 0; +  deferred_step_ptid = null_ptid;  }    /* This enum encodes possible reasons for doing a target_wait, so that @@ -924,7 +948,9 @@ struct execution_control_state  {    struct target_waitstatus ws;    struct target_waitstatus *wp; -  int another_trap; +  /* Should we step over breakpoint next time keep_going +     is called?  */ +  int stepping_over_breakpoint;    int random_signal;    CORE_ADDR stop_func_start;    CORE_ADDR stop_func_end; @@ -1085,7 +1111,7 @@ fetch_inferior_event (void *client_data)  void  init_execution_control_state (struct execution_control_state *ecs)  { -  ecs->another_trap = 0; +  ecs->stepping_over_breakpoint = 0;    ecs->random_signal = 0;    ecs->step_after_step_resume_breakpoint = 0;    ecs->handling_longjmp = 0;   /* FIXME */ @@ -1140,20 +1166,20 @@ context_switch (struct execution_control_state *ecs)      {                          /* Perform infrun state context switch: */        /* Save infrun state for the old thread.  */        save_infrun_state (inferior_ptid, prev_pc, -                        trap_expected, step_resume_breakpoint, +                        stepping_over_breakpoint, step_resume_breakpoint,                          step_range_start,                          step_range_end, &step_frame_id, -                        ecs->handling_longjmp, ecs->another_trap, +                        ecs->handling_longjmp, ecs->stepping_over_breakpoint,                          ecs->stepping_through_solib_after_catch,                          ecs->stepping_through_solib_catchpoints,                          ecs->current_line, ecs->current_symtab);          /* Load infrun state for the new thread.  */        load_infrun_state (ecs->ptid, &prev_pc, -                        &trap_expected, &step_resume_breakpoint, +                        &stepping_over_breakpoint, &step_resume_breakpoint,                          &step_range_start,                          &step_range_end, &step_frame_id, -                        &ecs->handling_longjmp, &ecs->another_trap, +                        &ecs->handling_longjmp, &ecs->stepping_over_breakpoint,                          &ecs->stepping_through_solib_after_catch,                          &ecs->stepping_through_solib_catchpoints,                          &ecs->current_line, &ecs->current_symtab); @@ -1620,17 +1646,15 @@ handle_inferior_event (struct execution_control_state *ecs)      stepping_past_singlestep_breakpoint = 0;   -  if (stepping_past_breakpoint) +  if (!ptid_equal (deferred_step_ptid, null_ptid))      { -      stepping_past_breakpoint = 0; -        /* If we stopped for some other reason than single-stepping, ignore          the fact that we were supposed to switch back.  */        if (stop_signal == TARGET_SIGNAL_TRAP)         {           if (debug_infrun)             fprintf_unfiltered (gdb_stdlog, -                               "infrun: stepping_past_breakpoint\n"); +                               "infrun: handling deferred step\n");             /* Pull the single step breakpoints out of the target.  */           if (singlestep_breakpoints_inserted_p) @@ -1641,7 +1665,8 @@ handle_inferior_event (struct execution_control_state *ecs)             /* Note: We do not call context_switch at this point, as the              context is already set up for stepping the original thread.  */ -         switch_to_thread (stepping_past_breakpoint_ptid); +         switch_to_thread (deferred_step_ptid); +         deferred_step_ptid = null_ptid;           /* Suppress spurious "Switching to ..." message.  */           previous_inferior_ptid = inferior_ptid;   @@ -1649,6 +1674,8 @@ handle_inferior_event (struct execution_control_state *ecs)           prepare_to_wait (ecs);           return;         } + +      deferred_step_ptid = null_ptid;      }      /* See if a thread hit a thread-specific breakpoint that was meant for @@ -1779,7 +1806,7 @@ handle_inferior_event (struct execution_control_state *ecs)                 context_switch (ecs);               ecs->waiton_ptid = ecs->ptid;               ecs->wp = &(ecs->ws); -             ecs->another_trap = 1; +             ecs->stepping_over_breakpoint = 1;                 ecs->infwait_state = infwait_thread_hop_state;               keep_going (ecs); @@ -1870,7 +1897,7 @@ handle_inferior_event (struct execution_control_state *ecs)                             &ecs->stop_func_start, &ecs->stop_func_end);    ecs->stop_func_start      += gdbarch_deprecated_function_start_offset (current_gdbarch); -  ecs->another_trap = 0; +  ecs->stepping_over_breakpoint = 0;    bpstat_clear (&stop_bpstat);    stop_step = 0;    stop_stack_dummy = 0; @@ -1879,7 +1906,7 @@ handle_inferior_event (struct execution_control_state *ecs)    stopped_by_random_signal = 0;      if (stop_signal == TARGET_SIGNAL_TRAP -      && trap_expected +      && stepping_over_breakpoint        && gdbarch_single_step_through_delay_p (current_gdbarch)        && currently_stepping (ecs))      { @@ -1897,7 +1924,7 @@ handle_inferior_event (struct execution_control_state *ecs)         {           /* The user issued a continue when stopped at a breakpoint.              Set up for another trap and get out of here.  */ -         ecs->another_trap = 1; +         ecs->stepping_over_breakpoint = 1;           keep_going (ecs);           return;         } @@ -1906,10 +1933,10 @@ handle_inferior_event (struct execution_control_state *ecs)           /* The user issued a step when stopped at a breakpoint.              Maybe we should stop, maybe we should not - the delay              slot *might* correspond to a line of source.  In any -            case, don't decide that here, just set ecs->another_trap, -            making sure we single-step again before breakpoints are -            re-inserted.  */ -         ecs->another_trap = 1; +            case, don't decide that here, just set +            ecs->stepping_over_breakpoint, making sure we +            single-step again before breakpoints are re-inserted.  */ +         ecs->stepping_over_breakpoint = 1;         }      }   @@ -1917,7 +1944,7 @@ handle_inferior_event (struct execution_control_state *ecs)       The alternatives are:       1) break; to really stop and return to the debugger,       2) drop through to start up again -     (set ecs->another_trap to 1 to single step once) +     (set ecs->stepping_over_breakpoint to 1 to single step once)       3) set ecs->random_signal to 1, and the decision between 1 and 2       will be made according to the signal handling tables.  */   @@ -2001,7 +2028,7 @@ handle_inferior_event (struct execution_control_state *ecs)        if (stop_signal == TARGET_SIGNAL_TRAP)         ecs->random_signal           = !(bpstat_explains_signal (stop_bpstat) -             || trap_expected +             || stepping_over_breakpoint               || (step_range_end && step_resume_breakpoint == NULL));        else         { @@ -2162,7 +2189,7 @@ process_event_stop_test:          if (debug_infrun)           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_SINGLE\n");         remove_breakpoints (); -       ecs->another_trap = 1; +       ecs->stepping_over_breakpoint = 1;         /* Still need to check other stuff, at least the case            where we are stepping and step out of the right range.  */         break; @@ -2223,7 +2250,7 @@ process_event_stop_test:                to doing that.  */             ecs->step_after_step_resume_breakpoint = 0;             remove_breakpoints (); -           ecs->another_trap = 1; +           ecs->stepping_over_breakpoint = 1;             keep_going (ecs);             return;           } @@ -2308,13 +2335,13 @@ process_event_stop_test:                 /* Be sure to lift all breakpoints, so the inferior does                  actually step past this point... */ -             ecs->another_trap = 1; +             ecs->stepping_over_breakpoint = 1;               break;             }           else             {               /* We want to step over this breakpoint, then keep going.  */ -             ecs->another_trap = 1; +             ecs->stepping_over_breakpoint = 1;               break;             }         } @@ -2345,7 +2372,7 @@ process_event_stop_test:         {            if (debug_infrun)             fprintf_unfiltered (gdb_stdlog, "infrun: stepping in dynamic linker\n"); -         ecs->another_trap = 1; +         ecs->stepping_over_breakpoint = 1;           keep_going (ecs);           return;         } @@ -2741,7 +2768,7 @@ currently_stepping (struct execution_control_state *ecs)  {    return ((!ecs->handling_longjmp            && ((step_range_end && step_resume_breakpoint == NULL) -              || trap_expected)) +              || stepping_over_breakpoint))           || ecs->stepping_through_solib_after_catch           || bpstat_should_step ());  } @@ -2920,7 +2947,7 @@ keep_going (struct execution_control_state *ecs)    /* If we did not do break;, it means we should keep running the       inferior and not return to debugger.  */   -  if (trap_expected && stop_signal != TARGET_SIGNAL_TRAP) +  if (stepping_over_breakpoint && stop_signal != TARGET_SIGNAL_TRAP)      {        /* We took a signal (which we are supposed to pass through to           the inferior, else we'd have done a break above) and we @@ -2942,7 +2969,7 @@ keep_going (struct execution_control_state *ecs)          already inserted breakpoints.  Therefore, we don't          care if breakpoints were already inserted, or not.  */         -      if (!ecs->another_trap) +      if (!ecs->stepping_over_breakpoint)         {           struct gdb_exception e;           /* Stop stepping when inserting breakpoints @@ -2958,7 +2985,7 @@ keep_going (struct execution_control_state *ecs)             }         }   -      trap_expected = ecs->another_trap; +      stepping_over_breakpoint = ecs->stepping_over_breakpoint;          /* Do not deliver SIGNAL_TRAP (except when the user explicitly           specifies that such a signal should be delivered to the @@ -3676,7 +3703,7 @@ struct inferior_status    int stop_step;    int stop_stack_dummy;    int stopped_by_random_signal; -  int trap_expected; +  int stepping_over_breakpoint;    CORE_ADDR step_range_start;    CORE_ADDR step_range_end;    struct frame_id step_frame_id; @@ -3722,7 +3749,7 @@ save_inferior_status (int restore_stack_info)    inf_status->stop_step = stop_step;    inf_status->stop_stack_dummy = stop_stack_dummy;    inf_status->stopped_by_random_signal = stopped_by_random_signal; -  inf_status->trap_expected = trap_expected; +  inf_status->stepping_over_breakpoint = stepping_over_breakpoint;    inf_status->step_range_start = step_range_start;    inf_status->step_range_end = step_range_end;    inf_status->step_frame_id = step_frame_id; @@ -3774,7 +3801,7 @@ restore_inferior_status (struct inferior_status *inf_status)    stop_step = inf_status->stop_step;    stop_stack_dummy = inf_status->stop_stack_dummy;    stopped_by_random_signal = inf_status->stopped_by_random_signal; -  trap_expected = inf_status->trap_expected; +  stepping_over_breakpoint = inf_status->stepping_over_breakpoint;    step_range_start = inf_status->step_range_start;    step_range_end = inf_status->step_range_end;    step_frame_id = inf_status->step_frame_id; diff --git a/gdb/thread.c b/gdb/thread.c index b6762e1..3c8644b 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -300,7 +300,7 @@ load_infrun_state (ptid_t ptid,                    CORE_ADDR *step_range_end,                    struct frame_id *step_frame_id,                    int *handling_longjmp, -                  int *another_trap, +                  int *stepping_over_breakpoint,                    int *stepping_through_solib_after_catch,                    bpstat *stepping_through_solib_catchpoints,                    int *current_line, @@ -321,7 +321,7 @@ load_infrun_state (ptid_t ptid,    *step_range_end = tp->step_range_end;    *step_frame_id = tp->step_frame_id;    *handling_longjmp = tp->handling_longjmp; -  *another_trap = tp->another_trap; +  *stepping_over_breakpoint = tp->stepping_over_breakpoint;    *stepping_through_solib_after_catch =      tp->stepping_through_solib_after_catch;    *stepping_through_solib_catchpoints = @@ -341,7 +341,7 @@ save_infrun_state (ptid_t ptid,                    CORE_ADDR step_range_end,                    const struct frame_id *step_frame_id,                    int handling_longjmp, -                  int another_trap, +                  int stepping_over_breakpoint,                    int stepping_through_solib_after_catch,                    bpstat stepping_through_solib_catchpoints,                    int current_line, @@ -362,7 +362,7 @@ save_infrun_state (ptid_t ptid,    tp->step_range_end = step_range_end;    tp->step_frame_id = (*step_frame_id);    tp->handling_longjmp = handling_longjmp; -  tp->another_trap = another_trap; +  tp->stepping_over_breakpoint = stepping_over_breakpoint;    tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;    tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;    tp->current_line = current_line; -- 1.5.3.5