public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Philippe Waroquiers <philippe.waroquiers@skynet.be>
To: gdb-patches@sourceware.org
Subject: Re: [RFAv3] Show locno for 'multi location' breakpoint hit msg+conv var $bkptno $locno.
Date: Mon, 08 Aug 2022 08:52:55 +0200	[thread overview]
Message-ID: <6924965eb4960b95081b251b2e467f8a203fdec4.camel@skynet.be> (raw)
In-Reply-To: <20220606094504.744323-1-philippe.waroquiers@skynet.be>

Ping ^ 6
(Eli reviewed the doc, Keith did a first review)

Thanks
Philippe


On Mon, 2022-06-06 at 11:45 +0200, Philippe Waroquiers wrote:
> Before this patch, when a breakpoint that has multiple locations is reached,
> GDB printed:
>   Thread 1 "zeoes" hit Breakpoint 1, some_func () at somefunc1.c:5
> 
> This patch changes the message so that bkpt_print_id prints the precise
> encountered breakpoint:
>   Thread 1 "zeoes" hit Breakpoint 1.2, some_func () at somefunc1.c:5
> 
> In mi mode, bkpt_print_id also (optionally) prints a new table field "locno":
>   locno is printed when the breakpoint has more than one location.
> Note that according to the GDB user manual node 'GDB/MI Development and Front
> Ends', it is ok to add new fields without changing the MI version.
> 
> Also, when a breakpoint is reached, the convenience variables
> $bkptno and $locno are set to the encountered breakpoint number
> and location number.
> 
> $bkptno and $locno can a.o. be used in the command list of a breakpoint,
> to disable the specific encountered breakpoint, e.g.
>    disable $bkptno.$locno
> 
> In case the breakpoint has only one location, $locno is still set to
> the value 1, so as to allow a command such as:
>   disable $bkptno.$locno
> even when the breakpoint has only one location.
> 
> This also fixes a strange behaviour: when a breakpoint X has only
> one location,
>   enable|disable X.1
> is accepted but transforms the breakpoint in a multiple locations
> breakpoint having only one location.
> 
> The changes in RFA v3 handle the additional comments of Eli:
>  GDB/NEW:
>   - Use max 80-column
>   - Use 'code location' instead of 'location'.
>   - Fix typo $bkpno
>   - Ensure that disable $bkptno and disable $bkptno.$locno have
>     each their explanation inthe example
>   - Reworded the 'breakpoint-hit' paragraph.
>  gdb.texinfo:
>   - Use 'code location' instead of 'location'.
>   - Add a note to clarify the distinction between $bkptno and $bpnum.
>   - Use @kbd instead of examples with only one command.
> 
> Compared to RFA v1, the changes in v2 handle the comments given by
> Keith Seitz and Eli Zaretskii:
>   - Use %s for the result of paddress
>   - Use bkptno_numopt_re instead of 2 different -re cases
>   - use C@t{++}
>   - Add index entries for $bkptno and $locno
>   - Added an example for "locno" in the mi interface
>   - Added examples in the Break command manual.
> ---
>  gdb/NEWS                                      | 21 +++++
>  gdb/ada-lang.c                                |  2 +-
>  gdb/break-catch-syscall.c                     |  2 +-
>  gdb/break-catch-throw.c                       |  2 +-
>  gdb/breakpoint.c                              | 93 +++++++++++++++----
>  gdb/breakpoint.h                              | 14 +++
>  gdb/doc/gdb.texinfo                           | 83 ++++++++++++++++-
>  gdb/infrun.c                                  | 16 +++-
>  gdb/testsuite/gdb.ada/bp_inlined_func.exp     |  2 +-
>  gdb/testsuite/gdb.ada/operator_bp.exp         |  4 +-
>  .../gdb.base/condbreak-multi-context.exp      |  8 +-
>  gdb/testsuite/gdb.base/ctxobj.exp             | 26 ++++--
>  gdb/testsuite/gdb.base/ena-dis-br.exp         | 41 ++++----
>  gdb/testsuite/gdb.base/foll-exec-mode.exp     |  6 +-
>  gdb/testsuite/gdb.base/pie-fork.exp           |  4 +-
>  gdb/testsuite/gdb.base/step-over-exit.exp     |  4 +-
>  gdb/testsuite/gdb.cp/mb-inline.exp            |  4 +-
>  gdb/testsuite/gdb.cp/mb-templates.exp         |  6 +-
>  gdb/testsuite/gdb.cp/ovldbreak.exp            |  6 +-
>  gdb/testsuite/gdb.gdb/python-helper.exp       |  4 +-
>  .../gdb.mi/interrupt-thread-group.exp         |  2 +-
>  .../gdb.mi/user-selected-context-sync.exp     | 35 +++++--
>  gdb/testsuite/gdb.multi/multi-arch-exec.exp   |  3 +-
>  .../gdb.multi/run-only-second-inf.exp         |  2 +-
>  .../gdb.multi/watchpoint-multi-exit.exp       |  4 +-
>  gdb/testsuite/gdb.multi/watchpoint-multi.exp  |  4 +-
>  gdb/testsuite/lib/gdb.exp                     | 11 ++-
>  gdb/testsuite/lib/mi-support.exp              | 20 +++-
>  28 files changed, 335 insertions(+), 94 deletions(-)
> 
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 960f90b4387..a5602deee2b 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -34,6 +34,21 @@
>       whitespace from each line before using the string as the help
>       output.
>  
> 
> +* When a breakpoint with multiple code locations is hit, GDB now prints
> +  the code location using the syntax <breakpoint_number>.<location_number>
> +  such as in:
> +     Thread 1 "zeoes" hit Breakpoint 2.3, some_func () at zeoes.c:8
> +
> +* When a breakpoint is hit, GDB now sets the convenience variables $bkptno and
> +  $locno to the hit breakpoint number and code location number.
> +  This allows to disable the last hit breakpoint using
> +     (gdb) disable $bkptno
> +   or disable only the specific breakpoint code location using
> +     (gdb) disable $bkptno.$locno
> +  These commands can be used inside the command list of a breakpoint to
> +  automatically disable the just encountered breakpoint (or the just
> +  encountered specific breakpoint code location).
> +
>  * New commands
>  
> 
>  maintenance set ignore-prologue-end-flag on|off
> @@ -50,6 +65,12 @@ maintenance info line-table
>    entry corresponds to an address where a breakpoint should be placed
>    to be at the first instruction past a function's prologue.
>  
> 
> +* MI changes
> +
> + ** The async record stating the stopped reason 'breakpoint-hit' now
> +    contains an optional field locno giving the code location number
> +    when the breakpoint has multiple code locations.
> +
>  * Python API
>  
> 
>    ** New function gdb.format_address(ADDRESS, PROGSPACE, ARCHITECTURE),
> diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
> index 6ab01fd27d4..bbae76f39ac 100644
> --- a/gdb/ada-lang.c
> +++ b/gdb/ada-lang.c
> @@ -12348,7 +12348,7 @@ ada_catchpoint::print_it (const bpstat *bs) const
>  
> 
>    uiout->text (disposition == disp_del
>  	       ? "\nTemporary catchpoint " : "\nCatchpoint ");
> -  uiout->field_signed ("bkptno", number);
> +  print_num_locno (bs, uiout);
>    uiout->text (", ");
>  
> 
>    /* ada_exception_name_addr relies on the selected frame being the
> diff --git a/gdb/break-catch-syscall.c b/gdb/break-catch-syscall.c
> index 06d48466de7..82229de33f7 100644
> --- a/gdb/break-catch-syscall.c
> +++ b/gdb/break-catch-syscall.c
> @@ -218,7 +218,7 @@ syscall_catchpoint::print_it (const bpstat *bs) const
>  						: EXEC_ASYNC_SYSCALL_RETURN));
>        uiout->field_string ("disp", bpdisp_text (b->disposition));
>      }
> -  uiout->field_signed ("bkptno", b->number);
> +  print_num_locno (bs, uiout);
>  
> 
>    if (last.kind () == TARGET_WAITKIND_SYSCALL_ENTRY)
>      uiout->text (" (call to syscall ");
> diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c
> index 66cf80be1c5..5b6f5d9eca1 100644
> --- a/gdb/break-catch-throw.c
> +++ b/gdb/break-catch-throw.c
> @@ -257,7 +257,7 @@ exception_catchpoint::print_it (const bpstat *bs) const
>    bp_temp = disposition == disp_del;
>    uiout->text (bp_temp ? "Temporary catchpoint "
>  		       : "Catchpoint ");
> -  uiout->field_signed ("bkptno", number);
> +  print_num_locno (bs, uiout);
>    uiout->text ((kind == EX_EVENT_THROW ? " (exception thrown), "
>  		: (kind == EX_EVENT_CATCH ? " (exception caught), "
>  		   : " (exception rethrown), ")));
> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
> index ed932a19ed7..c89c800f32f 100644
> --- a/gdb/breakpoint.c
> +++ b/gdb/breakpoint.c
> @@ -820,6 +820,19 @@ get_breakpoint (int num)
>    return nullptr;
>  }
>  
> 
> +/* Return TRUE if NUM refer to an existing breakpoint that has
> +   multiple code locations.  */
> +
> +static bool
> +has_multiple_locations (int num)
> +{
> +  for (breakpoint *b : all_breakpoints ())
> +    if (b->number == num)
> +      return b->loc != nullptr && b->loc->next != nullptr;
> +
> +  return false;
> +}
> +
>  \f
>  
> 
>  /* Mark locations as "conditions have changed" in case the target supports
> @@ -4451,15 +4464,7 @@ bpstat_explains_signal (bpstat *bsp, enum gdb_signal sig)
>    return false;
>  }
>  
> 
> -/* Put in *NUM the breakpoint number of the first breakpoint we are
> -   stopped at.  *BSP upon return is a bpstat which points to the
> -   remaining breakpoints stopped at (but which is not guaranteed to be
> -   good for anything but further calls to bpstat_num).
> -
> -   Return 0 if passed a bpstat which does not indicate any breakpoints.
> -   Return -1 if stopped at a breakpoint that has been deleted since
> -   we set it.
> -   Return 1 otherwise.  */
> +/* See breakpoint.h.  */
>  
> 
>  int
>  bpstat_num (bpstat **bsp, int *num)
> @@ -4481,6 +4486,57 @@ bpstat_num (bpstat **bsp, int *num)
>    return 1;
>  }
>  
> 
> +/* See breakpoint.h  */
> +
> +int
> +bpstat_locno (const bpstat *bs)
> +{
> +  const struct breakpoint *b = bs->breakpoint_at;
> +  const struct bp_location *bl = bs->bp_location_at.get ();
> +
> +  int locno = 0;
> +
> +  if (b != nullptr && b->loc->next != nullptr)
> +    {
> +      const bp_location *bl_i;
> +
> +      for (bl_i = b->loc;
> +	   bl_i != bl && bl_i->next != nullptr;
> +	   bl_i = bl_i->next)
> +	locno++;
> +
> +      if (bl_i == bl)
> +	locno++;
> +      else
> +	{
> +	  warning (_("location number not found for breakpoint %d address %s."),
> +		   b->number, paddress (bl->gdbarch, bl->address));
> +	  locno = 0;
> +	}
> +    }
> +
> +  return locno;
> +}
> +
> +/* See breakpoint.h.  */
> +
> +void
> +print_num_locno (const bpstat *bs, struct ui_out *uiout)
> +{
> +  struct breakpoint *b = bs->breakpoint_at;
> +
> +  if (b == nullptr)
> +    uiout->text (_("deleted breakpoint"));
> +  else
> +    {
> +      uiout->field_signed ("bkptno", b->number);
> +
> +      int locno = bpstat_locno (bs);
> +      if (locno != 0)
> +	uiout->message (".%pF", signed_field ("locno", locno));
> +    }
> +}
> +
>  /* See breakpoint.h.  */
>  
> 
>  void
> @@ -9176,7 +9232,7 @@ ranged_breakpoint::print_it (const bpstat *bs) const
>  		      async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
>        uiout->field_string ("disp", bpdisp_text (disposition));
>      }
> -  uiout->field_signed ("bkptno", number);
> +  print_num_locno (bs, uiout);
>    uiout->text (", ");
>  
> 
>    return PRINT_SRC_AND_LOC;
> @@ -11610,12 +11666,13 @@ ordinary_breakpoint::print_it (const bpstat *bs) const
>  			   async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
>        uiout->field_string ("disp", bpdisp_text (disposition));
>      }
> +
>    if (bp_temp)
> -    uiout->message ("Temporary breakpoint %pF, ",
> -		    signed_field ("bkptno", number));
> +    uiout->text ("Temporary breakpoint ");
>    else
> -    uiout->message ("Breakpoint %pF, ",
> -		    signed_field ("bkptno", number));
> +    uiout->text ("Breakpoint ");
> +  print_num_locno (bs, uiout);
> +  uiout->text (", ");
>  
> 
>    return PRINT_SRC_AND_LOC;
>  }
> @@ -13220,9 +13277,13 @@ enable_disable_command (const char *args, int from_tty, bool enable)
>  	  extract_bp_number_and_location (num, bp_num_range, bp_loc_range);
>  
> 
>  	  if (bp_loc_range.first == bp_loc_range.second
> -	      && bp_loc_range.first == 0)
> +	      && (bp_loc_range.first == 0
> +		  || (bp_loc_range.first == 1
> +		      && bp_num_range.first == bp_num_range.second
> +		      && !has_multiple_locations (bp_num_range.first))))
>  	    {
> -	      /* Handle breakpoint ids with formats 'x' or 'x-z'.  */
> +	      /* Handle breakpoint ids with formats 'x' or 'x-z'
> +		 or 'y.1' where y has only one code location.  */
>  	      map_breakpoint_number_range (bp_num_range,
>  					   enable
>  					   ? enable_breakpoint
> diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
> index 566f1285e46..96d61ef5427 100644
> --- a/gdb/breakpoint.h
> +++ b/gdb/breakpoint.h
> @@ -1231,6 +1231,20 @@ extern enum print_stop_action bpstat_print (bpstat *, int);
>     Return 1 otherwise.  */
>  extern int bpstat_num (bpstat **, int *);
>  
> 
> +/* If BS indicates a breakpoint and this breakpoint has several code locations,
> +   return the location number of BS, otherwise return 0.  */
> +
> +extern int bpstat_locno (const bpstat *bs);
> +
> +/* Print BS breakpoint number optionally followed by a . and breakpoint locno.
> +
> +   For a breakpoint with only one code location, outputs the signed field
> +   "bkptno" breakpoint number of BS (as returned by bpstat_num).
> +   If BS has several code locations, outputs a '.' character followed by
> +   the signed field "locno" (as returned by bpstat_locno).  */
> +
> +extern void print_num_locno (const bpstat *bs, struct ui_out *);
> +
>  /* Perform actions associated with the stopped inferior.  Actually, we
>     just use this for breakpoint commands.  Perhaps other actions will
>     go here later, but this is executed at a late time (from the
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index 434add3a663..391b81f8863 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -4338,9 +4338,65 @@ are operated on.
>  @cindex latest breakpoint
>  Breakpoints are set with the @code{break} command (abbreviated
>  @code{b}).  The debugger convenience variable @samp{$bpnum} records the
> -number of the breakpoint you've set most recently; see @ref{Convenience
> -Vars,, Convenience Variables}, for a discussion of what you can do with
> -convenience variables.
> +number of the breakpoint you've set most recently:
> +@smallexample
> +(gdb) b main
> +Breakpoint 1 at 0x11c6: file zeoes.c, line 24.
> +(gdb) p $bpnum
> +$1 = 1
> +@end smallexample
> +
> +A breakpoint may be mapped to multiple code locations for example with
> +inlined functions, Ada generics, C@t{++} templates or overloaded function names.
> +@value{GDBN} then indicates the number of code locations in the breakpoint
> +command output:
> +@smallexample
> +(gdb) b some_func
> +Breakpoint 2 at 0x1179: some_func. (3 locations)
> +(gdb) p $bpnum
> +$2 = 2
> +(gdb)
> +@end smallexample
> +
> +@vindex $bkptno@r{, convenience variable}
> +@vindex $locno@r{, convenience variable}
> +When your program stops on a breakpoint, the convenience variables
> +@samp{$bkptno} and @samp{$locno} are respectively set to the number of
> +the encountered breakpoint and the number of the breakpoint's code location:
> +@smallexample
> +Thread 1 "zeoes" hit Breakpoint 2.1, some_func () at zeoes.c:8
> +8	  printf("some func\n");
> +(gdb) p $bkptno
> +$5 = 2
> +(gdb) p $locno
> +$6 = 1
> +(gdb)
> +@end smallexample
> +
> +Note that @samp{$bkptno} and @samp{$bpnum} are not equivalent:
> +@samp{$bkptno} is set to the breakpoint number @b{last hit}, while
> +@samp{$bpnum} is set to the breakpoint number @b{last set}.
> +
> +
> +If the encountered breakpoint has only one code location, @samp{$locno} is set
> +to 1:
> +@smallexample
> +Breakpoint 1, main (argc=1, argv=0x7fffffffe018) at zeoes.c:24
> +24	  if (argc > 1)
> +(gdb) p $bkptno
> +$3 = 1
> +(gdb) p $locno
> +$4 = 1
> +(gdb)
> +@end smallexample
> +
> +The @samp{$bkptno} and @samp{$locno} variables can typically be used
> +in a breakpoint command list.
> +(@pxref{Break Commands, ,Breakpoint Command Lists}). For example, as
> +part of the breakpoint command list, you can disable completely the
> +encountered breakpoint using @samp{disable $bkptno} or disable the
> +specific encountered breakpoint location using @samp{disable
> +$bkptno.$locno}.
>  
> 
>  @table @code
>  @item break @var{locspec}
> @@ -5739,6 +5795,13 @@ Expressions}).
>  Pressing @key{RET} as a means of repeating the last @value{GDBN} command is
>  disabled within a @var{command-list}.
>  
> 
> +Inside a command list, you can use the command
> +@kbd{disable $bkptno} to disable the encountered breakpoint.
> +
> +If your breakpoint has several code locations, the command
> +@kbd{disable $bkptno.$locno} will disable the specific breakpoint code
> +location encountered.
> +
>  You can use breakpoint commands to start your program up again.  Simply
>  use the @code{continue} command, or @code{step}, or any other command
>  that resumes execution.
> @@ -32570,6 +32633,20 @@ line="13",arch="i386:x86_64"@}
>  (gdb)
>  @end smallexample
>  
> 
> +For a @samp{breakpoint-hit} stopped reason, when the breakpoint
> +encountered has multiple locations, the field @samp{bkptno} is
> +followed by the field @samp{locno}.
> +
> +@smallexample
> +-exec-continue
> +^running
> +(gdb)
> +@@Hello world
> +*stopped,reason="breakpoint-hit",disp="keep",bkptno="2",locno="3",frame=@{
> +func="foo",args=[],file="hello.c",fullname="/home/foo/bar/hello.c",
> +line="13",arch="i386:x86_64"@}
> +(gdb)
> +@end smallexample
>  
> 
>  @subheading The @code{-exec-finish} Command
>  @findex -exec-finish
> diff --git a/gdb/infrun.c b/gdb/infrun.c
> index 02c98b50c8c..e5ad062a914 100644
> --- a/gdb/infrun.c
> +++ b/gdb/infrun.c
> @@ -8494,7 +8494,21 @@ print_stop_location (const target_waitstatus &ws)
>       LOCATION: Print only location
>       SRC_AND_LOC: Print location and source line.  */
>    if (do_frame_printing)
> -    print_stack_frame (get_selected_frame (NULL), 0, source_flag, 1);
> +    {
> +      if (tp->control.stop_bpstat != nullptr)
> +	{
> +	  const struct breakpoint *b = tp->control.stop_bpstat->breakpoint_at;
> +
> +	  if (b != nullptr)
> +	    {
> +	      int locno = bpstat_locno (tp->control.stop_bpstat);
> +	      set_internalvar_integer (lookup_internalvar ("bkptno"), b->number);
> +	      set_internalvar_integer (lookup_internalvar ("locno"),
> +				       (locno > 0 ? locno : 1));
> +	    }
> +	}
> +      print_stack_frame (get_selected_frame (NULL), 0, source_flag, 1);
> +    }
>  }
>  
> 
>  /* See infrun.h.  */
> diff --git a/gdb/testsuite/gdb.ada/bp_inlined_func.exp b/gdb/testsuite/gdb.ada/bp_inlined_func.exp
> index 076e8c2425f..3f94c163819 100644
> --- a/gdb/testsuite/gdb.ada/bp_inlined_func.exp
> +++ b/gdb/testsuite/gdb.ada/bp_inlined_func.exp
> @@ -42,7 +42,7 @@ gdb_test "break read_small" \
>  for {set i 0} {$i < 4} {incr i} {
>      with_test_prefix "iteration $i" {
>  	gdb_test "continue" \
> -	    "Breakpoint $decimal, b\\.read_small \\(\\).*" \
> +	    "Breakpoint $bkptno_num_re, b\\.read_small \\(\\).*" \
>  	    "stopped in read_small"
>      }
>  }
> diff --git a/gdb/testsuite/gdb.ada/operator_bp.exp b/gdb/testsuite/gdb.ada/operator_bp.exp
> index 655e7af479f..e3928419ed6 100644
> --- a/gdb/testsuite/gdb.ada/operator_bp.exp
> +++ b/gdb/testsuite/gdb.ada/operator_bp.exp
> @@ -56,7 +56,7 @@ foreach op { "*" "/" "mod" "rem" "**" "<" "<=" ">" ">=" "=" "and" "or" "xor" "&"
>  foreach op { "+" "-" "*" "/" "mod" "rem" "**" "<" "<=" ">" ">=" "=" "and" "or" "xor" "&" "abs" "not"} {
>      set op_re [string_to_regexp $op]
>      gdb_test "continue" \
> -             "Breakpoint $decimal, ops\\.\"$op_re\" .*"\
> +             "Breakpoint $bkptno_numopt_re, ops\\.\"$op_re\" .*"\
>               "continue to \"$op\""
>  }
>  
> 
> @@ -86,7 +86,7 @@ foreach op { "*" "/" "mod" "rem" "**" "<" "<=" ">" ">=" "=" "and" "or" "xor" "&"
>  foreach op { "+" "-" "*" "/" "mod" "rem" "**" "<" "<=" ">" ">=" "=" "and" "or" "xor" "&" "abs" "not"} {
>      set op_re [string_to_regexp $op]
>      gdb_test "continue" \
> -             "Breakpoint $decimal, ops\\.\"$op_re\" .*"\
> +             "Breakpoint $bkptno_numopt_re, ops\\.\"$op_re\" .*"\
>               "continue to ops.\"$op\""
>  }
>  
> 
> diff --git a/gdb/testsuite/gdb.base/condbreak-multi-context.exp b/gdb/testsuite/gdb.base/condbreak-multi-context.exp
> index b540df973a3..742315178e3 100644
> --- a/gdb/testsuite/gdb.base/condbreak-multi-context.exp
> +++ b/gdb/testsuite/gdb.base/condbreak-multi-context.exp
> @@ -140,11 +140,11 @@ with_test_prefix "scenario 1" {
>      gdb_run_cmd
>  
> 
>      # Check our conditional breakpoints.
> -    gdb_test "" ".*Breakpoint \[0-9\]+, A::func .*" \
> +    gdb_test "" ".*Breakpoint $bkptno_num_re, A::func .*" \
>  	"run until A::func"
>      gdb_test "print a" " = 10"
>  
> 
> -    gdb_test "continue" "Continuing.*Breakpoint \[0-9\]+, C::func .*" \
> +    gdb_test "continue" "Continuing.*Breakpoint $bkptno_num_re, C::func .*" \
>  	"run until C::func"
>      gdb_test "print c" " = 30"
>  
> 
> @@ -208,11 +208,11 @@ with_test_prefix "scenario 2" {
>      gdb_run_cmd
>  
> 
>      # Check that we hit enabled locations only.
> -    gdb_test "" ".*Breakpoint \[0-9\]+, A::func .*" \
> +    gdb_test "" ".*Breakpoint $bkptno_num_re, A::func .*" \
>  	"run until A::func"
>      gdb_test "print a" " = 10"
>  
> 
> -    gdb_test "continue" "Continuing.*Breakpoint \[0-9\]+, C::func .*" \
> +    gdb_test "continue" "Continuing.*Breakpoint $bkptno_num_re, C::func .*" \
>  	"run until C::func"
>      gdb_test "print c" " = 30"
>  
> 
> diff --git a/gdb/testsuite/gdb.base/ctxobj.exp b/gdb/testsuite/gdb.base/ctxobj.exp
> index 9c010f54d79..0b589a7d6e6 100644
> --- a/gdb/testsuite/gdb.base/ctxobj.exp
> +++ b/gdb/testsuite/gdb.base/ctxobj.exp
> @@ -67,9 +67,16 @@ gdb_test "break ctxobj-f.c:$bp_location" \
>           "Breakpoint \[0-9\]+ at 0x\[0-9a-fA-F\]+: .*" \
>           "break in get_version functions"
>  
> 
> -gdb_test "continue" \
> -         "Breakpoint $decimal, get_version_1 \\(\\).*" \
> -         "continue to get_version_1"
> +global expect_out
> +set test "continue to get_version_1"
> +gdb_test_multiple "continue" $test {
> +    -re "Breakpoint ($bkptno_num_re), get_version_1 \\(\\).*" {
> +	set bpno $expect_out(1,string)
> +	pass $test
> +    }
> +}
> +# Verify the $bkptno.$locno convenience variables are set to the hit bpno.
> +gdb_test "printf \"%d.%d\\n\", \$bkptno, \$locno" "$bpno" "$test \$bkptno.\$locno is $bpno"
>  
> 
>  # Try printing "this_version_num".  There are two global variables
>  # with that name, and some systems such as GNU/Linux merge them
> @@ -100,10 +107,15 @@ gdb_test "print this_version_num == v" \
>          "print libctxobj1's this_version_num from symtab"
>  
> 
>  # Do the same, but from get_version_2.
> -
> -gdb_test "continue" \
> -         "Breakpoint $decimal, get_version_2 \\(\\).*" \
> -         "continue to get_version_2"
> +set test "continue to get_version_2"
> +gdb_test_multiple "continue" $test {
> +    -re "Breakpoint ($bkptno_num_re), get_version_2 \\(\\).*" {
> +	set bpno $expect_out(1,string)
> +	pass $test
> +    }
> +}
> +# Verify the $bkptno.$locno convenience variables are set to the hit bpno.
> +gdb_test "printf \"%d.%d\\n\", \$bkptno, \$locno" "$bpno" "$test \$bkptno.\$locno is $bpno"
>  
> 
>  gdb_test "print this_version_num == v" \
>           " = 1" \
> diff --git a/gdb/testsuite/gdb.base/ena-dis-br.exp b/gdb/testsuite/gdb.base/ena-dis-br.exp
> index 24925cf7185..04b3f134b44 100644
> --- a/gdb/testsuite/gdb.base/ena-dis-br.exp
> +++ b/gdb/testsuite/gdb.base/ena-dis-br.exp
> @@ -67,14 +67,21 @@ gdb_test "info break $bp" \
>  # See the comments in condbreak.exp for "run until breakpoint at
>  # marker1" for an explanation of the xfail below.
>  set test "continue to break marker1"
> +set bpno 0
>  gdb_test_multiple "continue" "$test" {
> -    -re "Breakpoint \[0-9\]*, marker1.*$gdb_prompt $" {
> +    -re "Breakpoint (\[0-9\]*), marker1.*$gdb_prompt $" {
> +	set bpno $expect_out(1,string)
>  	pass "$test"
>      }
> -    -re "Breakpoint \[0-9\]*, $hex in marker1.*$gdb_prompt $" {
> +    -re "Breakpoint (\[0-9\]*), $hex in marker1.*$gdb_prompt $" {
> +	set bpno $expect_out(1,string)
>  	xfail "$test"
>      }
>  }
> +# Verify the $bkptno convenience variable is equal to the hit bpno.
> +gdb_test "print \$bkptno" " = $bpno" "$test \$bkptno is $bpno"
> +# Verify the $locno is 1, as there is only one code location.
> +gdb_test "print \$locno" " = 1" "$test \$locno is 1"
>  
> 
>  gdb_test_no_output "delete $bp" "delete break marker1"
>  
> 
> @@ -359,7 +366,8 @@ with_test_prefix "4th breakpoint" {
>  }
>  
> 
>  # Perform tests for disable/enable commands on multiple
> -# locations and breakpoints.
> +# code locations and breakpoints.  If a breakpoint has only one code location,
> +# enable/disable num  and enable/disable num.1 should be equivalent.
>  #
>  # WHAT - the command to test (disable/enable).
>  #
> @@ -372,7 +380,7 @@ proc test_ena_dis_br { what } {
>      global b3
>      global b4
>      global gdb_prompt
> -    
> +
>      # OPPOS    - the command opposite to WHAT.
>      # WHAT_RES - whether breakpoints are expected to end
>      #            up enabled or disabled.
> @@ -395,13 +403,13 @@ proc test_ena_dis_br { what } {
>  	set p2 "pass"
>      }
>  
> 
> -    # Now enable(disable) $b.1 $b2.1.
> +    # Now enable(disable) $b1.1 $b2.1.
>      gdb_test_no_output "$what $b1.1 $b2.1" "$what \$b1.1 \$b2.1"
>      set test1 "${what}d \$b1.1 and \$b2.1"
>  
> 
>      # Now $b1.1 and $b2.1 should be enabled(disabled).
>      gdb_test_multiple "info break" "$test1" {
> -       -re "(${b1}.1)(\[^\n\r\]*)( n.*)(${b2}.1)(\[^\n\r\]*)( n.*)$gdb_prompt $" {
> +       -re "(${b1})(\[^\n\r\]*)( n.*)(${b2})(\[^\n\r\]*)( n.*)$gdb_prompt $" {
>             $p1 "$test1"
>         }
>         -re ".*$gdb_prompt $" {
> @@ -420,19 +428,16 @@ proc test_ena_dis_br { what } {
>         "${what}d \$b1"
>  
> 
>      gdb_test_no_output "$oppos $b3" "$oppos \$b3"
> +    # Now $b4 $b3 should be enabled(disabled)
> +    set test1 "${what}d \$b4 and \$b3"
> +    gdb_test "info break" "(${b3})(\[^\n\r]*)( $oppos_res.*).*(${b4})(\[^\n\r\]*)( $oppos_res.*)" "$test1"
> +
>      gdb_test_no_output "$what $b4 $b3.1" "$what \$b4 \$b3.1"
> -    set test1 "${what}d \$b4 and \$b3.1,remain ${oppos}d \$b3"
> +    set test1 "${what}d \$b4 and \$b3.1, changing \$b3"
> +
> +    # Now $b4 $b3 should be enabled(disabled)
> +    gdb_test "info break" "(${b3})(\[^\n\r]*)( $what_res.*).*(${b4})(\[^\n\r\]*)( $what_res.*)" "$test1"
>  
> 
> -    # Now $b4 $b3.1 should be enabled(disabled) and
> -    # $b3 should remain disabled(enabled).
> -    gdb_test_multiple "info break" "$test1" {
> -       -re "(${b3})(\[^\n\r]*)( $oppos_res.*)(${b3}.1)(\[^\n\r\]*)( n.*)(${b4})(\[^\n\r\]*)( $what_res.*)$gdb_prompt $" {
> -           $p1 "$test1"
> -       }
> -       -re "(${b3})(\[^\n\r]*)( $oppos_res.*)(${b4})(\[^\n\r\]*)( $what_res.*)$gdb_prompt $" {
> -           $p2 "$test1"
> -       }
> -    }
>  
> 
>      # Now enable(disable) '$b4.1 fooobaar'.  This should error on
>      # fooobaar.
> @@ -443,7 +448,7 @@ proc test_ena_dis_br { what } {
>  
> 
>      # $b4.1 should be enabled(disabled).
>      gdb_test_multiple "info break" "$test1" {
> -        -re "(${b4}.1)(\[^\n\r\]*)( n.*)$gdb_prompt $" {
> +        -re "(${b4})(\[^\n\r\]*)( n.*)$gdb_prompt $" {
>             $p1 "$test1"
>         }
>         -re ".*$gdb_prompt $" {
> diff --git a/gdb/testsuite/gdb.base/foll-exec-mode.exp b/gdb/testsuite/gdb.base/foll-exec-mode.exp
> index 918f3e4fd5f..cb6d975a767 100644
> --- a/gdb/testsuite/gdb.base/foll-exec-mode.exp
> +++ b/gdb/testsuite/gdb.base/foll-exec-mode.exp
> @@ -99,7 +99,7 @@ proc do_catch_exec_test { } {
>  # before re-running.
>  
> 
>  proc do_follow_exec_mode_tests { mode cmd infswitch } {
> -    global binfile srcfile srcfile2 testfile testfile2
> +    global binfile srcfile srcfile2 testfile testfile2 bkptno_numopt_re
>      global gdb_prompt
>  
> 
>      with_test_prefix "$mode,$cmd,$infswitch" {
> @@ -125,7 +125,7 @@ proc do_follow_exec_mode_tests { mode cmd infswitch } {
>  	# Set up the output we expect to see after we execute past the exec.
>  	#
>  	set execd_line [gdb_get_line_number "after-exec" $srcfile2]
> -	set expected_re ".*xecuting new program: .*${testfile2}.*Breakpoint .,.*${srcfile2}:${execd_line}.*$gdb_prompt $"
> +	set expected_re ".*xecuting new program: .*${testfile2}.*Breakpoint ${bkptno_numopt_re},.*${srcfile2}:${execd_line}.*$gdb_prompt $"
>  
> 
>  	# Set a breakpoint after the exec call if we aren't single-stepping
>  	# past it.
> @@ -189,7 +189,7 @@ proc do_follow_exec_mode_tests { mode cmd infswitch } {
>  		send_gdb "y\n"
>  		exp_continue
>  	    }
> -	    -re "Starting program: .*$expected_inf.*Breakpoint .,.*\r\n$gdb_prompt $" {
> +	    -re "Starting program: .*$expected_inf.*Breakpoint $bkptno_numopt_re,.*\r\n$gdb_prompt $" {
>  		pass $test
>  	    }
>  	}
> diff --git a/gdb/testsuite/gdb.base/pie-fork.exp b/gdb/testsuite/gdb.base/pie-fork.exp
> index efc357d39a2..19e9d3a5537 100644
> --- a/gdb/testsuite/gdb.base/pie-fork.exp
> +++ b/gdb/testsuite/gdb.base/pie-fork.exp
> @@ -54,10 +54,10 @@ proc_with_prefix test_detach_on_fork_follow_child {} {
>  proc_with_prefix test_no_detach_on_fork {} {
>      setup_test "off"
>  
> 
> -    gdb_test "continue" "\r\nThread 1.1 .* hit Breakpoint 2, break_here.*" \
> +    gdb_test "continue" "\r\nThread 1.1 .* hit Breakpoint 2.1, break_here.*" \
>  	     "continue from thread 1.1"
>      gdb_test "thread 2.1"
> -    gdb_test "continue" "\r\nThread 2.1 .* hit Breakpoint 2, break_here.*" \
> +    gdb_test "continue" "\r\nThread 2.1 .* hit Breakpoint 2.2, break_here.*" \
>  	     "continue from thread 2.1"
>  }
>  
> 
> diff --git a/gdb/testsuite/gdb.base/step-over-exit.exp b/gdb/testsuite/gdb.base/step-over-exit.exp
> index f8bd99980fe..575319c564c 100644
> --- a/gdb/testsuite/gdb.base/step-over-exit.exp
> +++ b/gdb/testsuite/gdb.base/step-over-exit.exp
> @@ -91,7 +91,7 @@ delete_breakpoints
>  
> 
>  gdb_test "break marker"
>  
> 
> -gdb_test "continue" "Continuing\\..*Breakpoint $decimal, .*" \
> +gdb_test "continue" "Continuing\\..*Breakpoint $bkptno_num_re, .*" \
>      "continue to marker, first time"
>  
> 
>  # Step 2, create a breakpoint which evaluates false, and force it
> @@ -120,5 +120,5 @@ gdb_test "inferior 1" ".*Switching to inferior 1.*" \
>  # Switch back to the parent process, continue to the marker to
>  # test GDBserver's state is still correct.
>  
> 
> -gdb_test "continue" "Continuing\\..*Breakpoint $decimal, .*" \
> +gdb_test "continue" "Continuing\\..*Breakpoint $bkptno_numopt_re, .*" \
>      "continue to marker, second time"
> diff --git a/gdb/testsuite/gdb.cp/mb-inline.exp b/gdb/testsuite/gdb.cp/mb-inline.exp
> index 47a2a5dcb7c..fa098602c31 100644
> --- a/gdb/testsuite/gdb.cp/mb-inline.exp
> +++ b/gdb/testsuite/gdb.cp/mb-inline.exp
> @@ -46,7 +46,7 @@ gdb_test "info break" \
>      "\[\r\n\]1\.1.* y .* at .*$hdrfile:$bp_location.*\[\r\n\]1\.2.* y .* at .*$hdrfile:$bp_location.*"
>  
> 
>  gdb_run_cmd
> -gdb_test "" "Breakpoint \[0-9\]+,.*foo \\(i=0\\).*" "run to breakpoint"
> +gdb_test "" "Breakpoint $bkptno_num_re,.*foo \\(i=0\\).*" "run to breakpoint"
>  
> 
>  gdb_test "continue" \
>      ".*Breakpoint.*foo \\(i=1\\).*" \
> @@ -59,7 +59,7 @@ gdb_test "continue" \
>  gdb_test_no_output "disable 1.2" "disabling location: disable"
>  
> 
>  gdb_run_cmd
> -gdb_test "" "Breakpoint \[0-9\]+,.*foo \\(i=0\\).*" "disabling location: run to breakpoint"
> +gdb_test "" "Breakpoint $bkptno_num_re,.*foo \\(i=0\\).*" "disabling location: run to breakpoint"
>  
> 
>  gdb_test_multiple "info break" "disabled breakpoint 1.2" {
>      -re "1\.2.* n .* at .*$hdrfile:$bp_location.*$gdb_prompt $" {
> diff --git a/gdb/testsuite/gdb.cp/mb-templates.exp b/gdb/testsuite/gdb.cp/mb-templates.exp
> index 6c988e7335e..0c0d46fcb7a 100644
> --- a/gdb/testsuite/gdb.cp/mb-templates.exp
> +++ b/gdb/testsuite/gdb.cp/mb-templates.exp
> @@ -42,7 +42,7 @@ gdb_run_cmd
>  
> 
>  set test "initial condition: run to breakpoint"
>  gdb_test_multiple "" $test {
> -    -re "Breakpoint \[0-9\]+,.*foo<int> \\(i=1\\).*$gdb_prompt $" {
> +    -re "Breakpoint $bkptno_num_re,.*foo<int> \\(i=1\\).*$gdb_prompt $" {
>  	pass $test
>  	break
>      }
> @@ -67,7 +67,7 @@ gdb_test_no_output {condition $bpnum i==1} \
>      "separate condition: set condition"
>      
> 
>  gdb_run_cmd
> -gdb_test "" "Breakpoint \[0-9\]+,.*foo<int> \\(i=1\\).*" "separate condition: run to breakpoint"
> +gdb_test "" "Breakpoint $bkptno_num_re,.*foo<int> \\(i=1\\).*" "separate condition: run to breakpoint"
>  
> 
>  gdb_test "continue" \
>      ".*Breakpoint.*foo<double> \\(i=1\\).*" \
> @@ -79,7 +79,7 @@ gdb_test "continue" \
>  gdb_test_no_output {disable $bpnum.1} "disabling location: disable"
>  
> 
>  gdb_run_cmd
> -gdb_test "" "Breakpoint \[0-9\]+,.*foo<double> \\(i=1\\).*" "disabling location: run to breakpoint"
> +gdb_test "" "Breakpoint $bkptno_num_re,.*foo<double> \\(i=1\\).*" "disabling location: run to breakpoint"
>  
> 
>  # Try disabling entire breakpoint
>  gdb_test_no_output {enable $bpnum.1} "disabling location: enable"
> diff --git a/gdb/testsuite/gdb.cp/ovldbreak.exp b/gdb/testsuite/gdb.cp/ovldbreak.exp
> index 06adf82ecbb..0ed9eae055b 100644
> --- a/gdb/testsuite/gdb.cp/ovldbreak.exp
> +++ b/gdb/testsuite/gdb.cp/ovldbreak.exp
> @@ -380,7 +380,7 @@ gdb_test "info break" $bptable "breakpoint info (after setting on all)"
>  
> 
>  # Run through each breakpoint.
>  proc continue_to_bp_overloaded {bpnumber might_fail line argtype argument} {
> -    global gdb_prompt hex decimal srcfile
> +    global gdb_prompt hex decimal srcfile bkptno_num_re
>  
> 
>      if {$argument == ""} {
>          set actuals ""
> @@ -398,11 +398,11 @@ proc continue_to_bp_overloaded {bpnumber might_fail line argtype argument} {
>      }
>  
> 
>      gdb_test_multiple "continue" "continue to bp overloaded : $argtype" {
> -        -re "Continuing.\r\n\r\nBreakpoint $bpnumber, foo::overload1arg \\(this=${hex}(, )?$actuals\\) at .*$srcfile:$line\r\n$decimal\[\t \]+{ $body }.*$gdb_prompt $" {
> +        -re "Continuing.\r\n\r\nBreakpoint $bkptno_num_re, foo::overload1arg \\(this=${hex}(, )?$actuals\\) at .*$srcfile:$line\r\n$decimal\[\t \]+{ $body }.*$gdb_prompt $" {
>              pass "continue to bp overloaded : $argtype"
>          }
>  
> 
> -        -re "Continuing.\r\n\r\nBreakpoint $bpnumber, foo::overload1arg \\(this=${hex}, arg=.*\\) at .*$srcfile:$line\r\n$decimal\[\t \]+{ $body }.*$gdb_prompt $" {
> +        -re "Continuing.\r\n\r\nBreakpoint $bkptno_num_re, foo::overload1arg \\(this=${hex}, arg=.*\\) at .*$srcfile:$line\r\n$decimal\[\t \]+{ $body }.*$gdb_prompt $" {
>              if $might_kfail {
>                  kfail "c++/8130" "continue to bp overloaded : $argtype"
>              } else {
> diff --git a/gdb/testsuite/gdb.gdb/python-helper.exp b/gdb/testsuite/gdb.gdb/python-helper.exp
> index 6db8bf0df50..30eb6038f3a 100644
> --- a/gdb/testsuite/gdb.gdb/python-helper.exp
> +++ b/gdb/testsuite/gdb.gdb/python-helper.exp
> @@ -49,7 +49,7 @@ gdb_exit
>  # The main test.  This is called by the self-test framework once GDB
>  # has been started on a copy of itself.
>  proc test_python_helper {} {
> -    global py_helper_script decimal hex gdb_prompt
> +    global py_helper_script decimal hex gdb_prompt bkptno_numopt_re
>      global inferior_spawn_id
>  
> 
>      # Source the python helper script.  This script registers the
> @@ -233,7 +233,7 @@ proc test_python_helper {} {
>      # GDB stopping at the value_print breakpoint again.
>      send_inferior "ptype global_c\n"
>      gdb_test_multiple "" "hit breakpoint in outer gdb again" {
> -	-re "Breakpoint $decimal, c_print_type .*\\(outer-gdb\\) $" {
> +	-re "Breakpoint $bkptno_numopt_re, c_print_type .*\\(outer-gdb\\) $" {
>  	    pass $gdb_test_name
>  	}
>      }
> diff --git a/gdb/testsuite/gdb.mi/interrupt-thread-group.exp b/gdb/testsuite/gdb.mi/interrupt-thread-group.exp
> index 19ccbe85e04..c080955049c 100644
> --- a/gdb/testsuite/gdb.mi/interrupt-thread-group.exp
> +++ b/gdb/testsuite/gdb.mi/interrupt-thread-group.exp
> @@ -69,7 +69,7 @@ if { $use_second_inferior } {
>  	"\\^running.*" \
>  	"run inferior 2"
>  
> 
> -    mi_expect_stop "breakpoint-hit" "all_threads_started" ".*" ".*" ".*" {"" "disp=\"keep\""} \
> +    mi_expect_stop "breakpoint-hit" "all_threads_started" ".*" ".*" ".*" {"" "disp=\"keep\"" "locno=\"[0-9]+\""} \
>  	"inferior i2 stops at all_threads_started"
>  
> 
>      mi_send_resuming_command "exec-continue --thread-group i2" \
> diff --git a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
> index d78c96ddef1..9eec083068b 100644
> --- a/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
> +++ b/gdb/testsuite/gdb.mi/user-selected-context-sync.exp
> @@ -307,8 +307,13 @@ proc test_continue_to_start { mode inf } {
>  
> 
>  	    # Consume MI event output.
>  	    with_spawn_id $mi_spawn_id {
> -		mi_expect_stop "breakpoint-hit" "main" "" "$srcfile" \
> -		    "$decimal" {"" "disp=\"del\""} "stop at breakpoint in main"
> +		if { $inf == 1 } {
> +		    mi_expect_stop "breakpoint-hit" "main" "" "$srcfile" \
> +			"$decimal" {"" "disp=\"del\""} "stop at breakpoint in main"
> +		} else {
> +		    mi_expect_stop "breakpoint-hit" "main" "" "$srcfile" \
> +			"$decimal" {"" "disp=\"del\"" "locno=\"[0-9]+\""} "stop at breakpoint in main"
> +		}
>  	    }
>  
> 
>  	    if { $mode == "all-stop" } {
> @@ -330,9 +335,15 @@ proc test_continue_to_start { mode inf } {
>  
> 
>  		    # Consume MI output.
>  		    with_spawn_id $mi_spawn_id {
> -			mi_expect_stop "breakpoint-hit" "child_sub_function" \
> -			    "" "$srcfile" "$decimal" {"" "disp=\"del\""} \
> -			    "thread $inf.$thread stops MI"
> +			if { $inf == 1} {
> +			    mi_expect_stop "breakpoint-hit" "child_sub_function" \
> +				"" "$srcfile" "$decimal" {"" "disp=\"del\""} \
> +				"thread $inf.$thread stops MI"
> +			} else {
> +			    mi_expect_stop "breakpoint-hit" "child_sub_function" \
> +				"" "$srcfile" "$decimal" {"" "disp=\"del\"" "locno=\"[0-9]+\""} \
> +				"thread $inf.$thread stops MI"
> +			}
>  		    }
>  		}
>  
> 
> @@ -359,9 +370,15 @@ proc test_continue_to_start { mode inf } {
>  
> 
>  		# Consume MI output.
>  		with_spawn_id $mi_spawn_id {
> -		    mi_expect_stop "breakpoint-hit" "child_sub_function" \
> -			"" "$srcfile" "$decimal" {"" "disp=\"del\""} \
> -			"thread $inf.2 stops MI"
> +		    if { $inf == 1} {
> +			mi_expect_stop "breakpoint-hit" "child_sub_function" \
> +			    "" "$srcfile" "$decimal" {"" "disp=\"del\""} \
> +			    "thread $inf.2 stops MI"
> +		    } else {
> +			mi_expect_stop "breakpoint-hit" "child_sub_function" \
> +			    "" "$srcfile" "$decimal" {"" "disp=\"del\"" "locno=\"[0-9]+\""} \
> +			    "thread $inf.2 stops MI"
> +		    }
>  		}
>  	    }
>  	}
> @@ -434,7 +451,7 @@ proc_with_prefix test_setup { mode } {
>  
> 
>  	with_spawn_id $mi_spawn_id {
>  	    mi_expect_stop "breakpoint-hit" "main" "" "$srcfile" "$decimal" \
> -		{"" "disp=\"del\""} "main stop"
> +		{"" "disp=\"del\"" "locno=\"[0-9]+\""} "main stop"
>  	}
>  
> 
>  	# Consume CLI output.
> diff --git a/gdb/testsuite/gdb.multi/multi-arch-exec.exp b/gdb/testsuite/gdb.multi/multi-arch-exec.exp
> index a1496fb5571..dfdb746c65e 100644
> --- a/gdb/testsuite/gdb.multi/multi-arch-exec.exp
> +++ b/gdb/testsuite/gdb.multi/multi-arch-exec.exp
> @@ -148,6 +148,7 @@ proc build_executables { first_arch } {
>  }
>  
> 
>  proc do_test { first_arch mode selected_thread } {
> +        global bkptno_numopt_re
>  	set from_exec "$first_arch-multi-arch-exec"
>  
> 
>  	clean_restart ${from_exec}
> @@ -169,7 +170,7 @@ proc do_test { first_arch mode selected_thread } {
>  
> 
>  	# Test that GDB updates the target description / arch successfuly
>  	# after the exec.
> -	gdb_test "continue" "Breakpoint 2, main.*" "continue across exec that changes architecture"
> +	gdb_test "continue" "Breakpoint $bkptno_numopt_re, main.*" "continue across exec that changes architecture"
>  }
>  
> 
>  # Test both arch1=>arch2 and arch2=>arch1.
> diff --git a/gdb/testsuite/gdb.multi/run-only-second-inf.exp b/gdb/testsuite/gdb.multi/run-only-second-inf.exp
> index fec2575f904..b94689d0bfa 100644
> --- a/gdb/testsuite/gdb.multi/run-only-second-inf.exp
> +++ b/gdb/testsuite/gdb.multi/run-only-second-inf.exp
> @@ -46,5 +46,5 @@ gdb_load $binfile
>  if {[gdb_start_cmd] < 0} {
>      fail "start the second inf"
>  } else {
> -    gdb_test "" ".*reakpoint ., main .*${srcfile}.*" "start the second inf"
> +    gdb_test "" ".*reakpoint $bkptno_numopt_re, main .*${srcfile}.*" "start the second inf"
>  }
> diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp b/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp
> index cbccba19d12..3c079facced 100644
> --- a/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp
> +++ b/gdb/testsuite/gdb.multi/watchpoint-multi-exit.exp
> @@ -27,7 +27,7 @@ if {[build_executable "failed to build" $testfile $srcfile {debug}]} {
>  # child.  Can be either "kill", "detach", or "exit" (to continue it to
>  # normal exit).
>  proc do_test {dispose} {
> -    global binfile
> +    global binfile bkptno_numopt_re
>  
> 
>      clean_restart $binfile
>  
> 
> @@ -77,7 +77,7 @@ proc do_test {dispose} {
>      #  Command aborted.
>      #  (gdb)
>      #
> -    gdb_test "continue" "Breakpoint \[0-9\]+, marker .*" \
> +    gdb_test "continue" "Breakpoint $bkptno_numopt_re, marker .*" \
>  	"continue in inferior 1"
>  }
>  
> 
> diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi.exp b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
> index e4329dca6c2..0fc1bee762f 100644
> --- a/gdb/testsuite/gdb.multi/watchpoint-multi.exp
> +++ b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
> @@ -84,11 +84,11 @@ if [skip_hw_watchpoint_multi_tests] {
>  	"Hardware access \\(read/write\\) watchpoint \[0-9\]+: c\r\n\r\nOld value = 0\r\nNew value = 3\r\n.*" \
>  	"catch c on inferior 2"
>  
> 
> -    gdb_test "continue" "Breakpoint \[0-9\]+, marker_exit .*" "catch marker_exit in inferior 2"
> +    gdb_test "continue" "Breakpoint $bkptno_numopt_re, marker_exit .*" "catch marker_exit in inferior 2"
>  
> 
>      gdb_test "inferior 1" "witching to inferior 1 .*" "switch back to inferior 1 again"
>  
> 
>      gdb_test "continue" "Hardware access \\(read/write\\) watchpoint \[0-9\]+: b\r\n\r\nOld value = 0\r\nNew value = 2\r\n.*" "catch b on inferior 1"
>  }
>  
> 
> -gdb_test "continue" "Breakpoint \[0-9\]+, marker_exit .*" "catch marker_exit in inferior 1"
> +gdb_test "continue" "Breakpoint $bkptno_numopt_re, marker_exit .*" "catch marker_exit in inferior 1"
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index 402450152ac..5e4c793598e 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -227,6 +227,14 @@ set inferior_exited_re "(?:\\\[Inferior \[0-9\]+ \\(\[^\n\r\]*\\) exited)"
>  # E.g., $1, $2, etc.
>  set valnum_re "\\\$$decimal"
>  
> 
> +# A regular expression that matches a breakpoint hit with a breakpoint
> +# having several code locations.
> +set bkptno_num_re "$decimal\\.$decimal"
> +
> +# A regular expression that matches a breakpoint hit
> +# with one or several code locations.
> +set bkptno_numopt_re "($decimal\\.$decimal|$decimal)"
> +
>  ### Only procedures should come after this point.
>  
> 
>  #
> @@ -662,6 +670,7 @@ proc gdb_breakpoint { linespec args } {
>  
> 
>  proc runto { linespec args } {
>      global gdb_prompt
> +    global bkptno_numopt_re
>      global decimal
>  
> 
>      delete_breakpoints
> @@ -699,7 +708,7 @@ proc runto { linespec args } {
>  	    }
>  	    return 1
>  	}
> -	-re "Breakpoint \[0-9\]*, \[0-9xa-f\]* in .*$gdb_prompt $" { 
> +	-re "Breakpoint $bkptno_numopt_re, \[0-9xa-f\]* in .*$gdb_prompt $" {
>  	    if { $print_pass } {
>  		pass $test_name
>  	    }
> diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
> index e578a7e6f9b..ea66fdcabf8 100644
> --- a/gdb/testsuite/lib/mi-support.exp
> +++ b/gdb/testsuite/lib/mi-support.exp
> @@ -1195,11 +1195,11 @@ proc mi_detect_async {} {
>  # filename of a file without debug info.  ARGS should not include [] the
>  # list of argument is enclosed in, and other regular expressions should
>  # not include quotes.
> -# If EXTRA is a list of one element, it's the regular expression
> +# EXTRA can be a list of one, two or three elements.
> +# The first element is the regular expression
>  # for output expected right after *stopped, and before GDB prompt.
> -# If EXTRA is a list of two elements, the first element is for
> -# output right after *stopped, and the second element is output
> -# right after reason field.  The regex after reason should not include
> +# The third element is the regulation expression for the locno
> +# right after bkptno field.  The locno regex should not include
>  # the comma separating it from the following fields.
>  #
>  # When we fail to match output at all, -1 is returned.  If FILE does
> @@ -1224,7 +1224,14 @@ proc mi_expect_stop { reason func args file line extra test } {
>  
> 
>      set after_stopped ""
>      set after_reason ""
> -    if { [llength $extra] == 2 } {
> +    set locno ""
> +    if { [llength $extra] == 3 } {
> +	set after_stopped [lindex $extra 0]
> +	set after_reason [lindex $extra 1]
> +	set after_reason "${after_reason},"
> +	set locno [lindex $extra 2]
> +	set locno "${locno},"
> +    } elseif { [llength $extra] == 2 } {
>  	set after_stopped [lindex $extra 0]
>  	set after_reason [lindex $extra 1]
>  	set after_reason "${after_reason},"
> @@ -1298,10 +1305,12 @@ proc mi_expect_stop { reason func args file line extra test } {
>      set ebn ""
>      if { $reason == "breakpoint-hit" } {
>  	set bn {bkptno="[0-9]+",}
> +	set bn "${bn}${locno}"
>      } elseif { $reason == "solib-event" } {
>  	set bn ".*"
>      } elseif { $reason == "exception-caught" } {
>  	set ebn {bkptno="[0-9]+",}
> +	set ebn "${ebn}${locno}"
>  	set bn ".*"
>  	set reason "breakpoint-hit"
>      }
> @@ -1315,6 +1324,7 @@ proc mi_expect_stop { reason func args file line extra test } {
>      set a $after_reason
>  
> 
>      verbose -log "mi_expect_stop: expecting: \\*stopped,${ebn}${r}${a}${bn}frame=\{addr=\"$hex\",func=\"$func\",args=$args,(?:file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"$line\",arch=\"$any\"|from=\"$file\")\}$after_stopped,thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$prompt_re"
> +
>      gdb_expect {
>  	-re "\\*stopped,${ebn}${r}${a}${bn}frame=\{addr=\"$hex\",func=\"$func\",args=$args,(?:file=\"$any$file\",fullname=\"${fullname_syntax}$file\",line=\"($line)\",arch=\"$any\"|from=\"$file\")\}$after_stopped,thread-id=\"$decimal\",stopped-threads=$any\r\n($thread_selected_re|$breakpoint_re)*$prompt_re" {
>  	    pass "$test"



  parent reply	other threads:[~2022-08-08  6:52 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-06  9:45 Philippe Waroquiers
2022-06-06 10:53 ` Eli Zaretskii
2022-06-13 17:51 ` Philippe Waroquiers
2022-06-14 17:32   ` Keith Seitz
2022-06-14 17:41     ` Eli Zaretskii
2022-06-14 21:27       ` Philippe Waroquiers
2022-06-19 17:46 ` Philippe Waroquiers
2022-06-26 17:27 ` Philippe Waroquiers
2022-07-22 16:57 ` Philippe Waroquiers
2022-07-29 18:56 ` Philippe Waroquiers
2022-08-08  6:52 ` Philippe Waroquiers [this message]
2022-08-14 14:08 ` Philippe Waroquiers
2022-08-21 12:05 ` Philippe Waroquiers
2022-08-27 14:45 ` Philippe Waroquiers
2022-09-03 15:17 ` ping^10 " Philippe Waroquiers
2022-11-10 15:57 ` Tom Tromey
2022-11-12 16:15   ` Philippe Waroquiers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6924965eb4960b95081b251b2e467f8a203fdec4.camel@skynet.be \
    --to=philippe.waroquiers@skynet.be \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).