"catch catch/throw/rethrow", breakpoint -> catchpoint

Currently, with:

 (gdb) catch catch
 Catchpoint 1 (catch)
 (gdb) catch throw
 Catchpoint 2 (throw)
 (gdb) catch rethrow
 Catchpoint 3 (rethrow)

You get:

(gdb) info breakpoints
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   0x0000000000b122af exception catch
 2       breakpoint     keep y   0x0000000000b1288d exception throw
 3       breakpoint     keep y   0x0000000000b12931 exception rethrow

I think it doesn't make much sense usability-wise, to show a
catchpoint as a breakpoint.  The fact that GDB sets a breakpoint at
some magic address in the C++ run time is an implementation detail,
IMO.  And as seen in the previous patch, such a catchpoint can end up
with more than one location/address even, so showing a single address
isn't entirely accurate.

This commit hides the addresses from view, and makes GDB show
"catchpoint" for type as well:

  (gdb) info breakpoints
  Num     Type           Disp Enb Address            What
  1       catchpoint     keep y                      exception catch
  2       catchpoint     keep y                      exception throw
  3       catchpoint     keep y                      exception rethrow

This comment in the code seems telling:

  /* We need to reset 'type' in order for code in breakpoint.c to do
     the right thing.  */
  cp->type = bp_breakpoint;

It kind of suggests that the reason catchpoints end up shown as
breakpoints was that it was easier to implement them that way, rather
than a desired property.

This commit fixes things up to make it possible to have bp_catch
breakpoints have software/hardware breakpoint locations, thus
eliminating the need for that hack:

 - redo breakpoint_address_is_meaningful in terms of the location's
   type rather than breakpoint type.
 - teach bpstat_what about stepping over the catchpoint locations.
 - install a allocate_location method for "catch catch/throw/rethrow",
   one that forces the location type.

Note that this also reverts the gdb hunk from:

  commit 2a8be20359
  Commit:     Tom Tromey <tom@tromey.com>
  CommitDate: Sat Oct 6 22:17:45 2018 -0600

      Fix Python gdb.Breakpoint.location crash

because now "catch throw" catchpoints hit the

   if (obj->bp->type != bp_breakpoint)
     Py_RETURN_NONE;

check above, and, adjusts the testcase to no longer expect to see the
catchpoint in the gdb.breakpoints() list.

(Note: might make sense to do the same to Ada exception catchpoints.)

gdb/ChangeLog:
2019-07-09  Pedro Alves  <palves@redhat.com>

	* break-catch-throw.c (print_one_exception_catchpoint): Skip the
	"addr" field.
	(allocate_location_exception_catchpoint): New.
	(handle_gnu_v3_exceptions): Don't reset 'type' to bp_breakpoint.
	(initialize_throw_catchpoint_ops): Install
	allocate_location_exception_catchpoint as allocate_location
	method.
	* breakpoint.c (bpstat_what) <bp_catch>: Set action to
	BPSTAT_WHAT_SINGLE if not stopping and the location's type is not
	bp_loc_other.
	(breakpoint_address_is_meaningful): Delete.
	(bl_address_is_meaningful): New.
	(breakpoint_locations_match): Adjust comment.
	(bp_location_from_bp_type): New, factored out of...
	(bp_location::bp_location(breakpoint *)): ... this.
	(bp_location::bp_location(breakpoint *, bp_loc_type)): New,
	factored out of...
	(bp_location::bp_location(breakpoint *)): ... this.  Reimplement.
	(bp_loc_is_permanent): Use bl_address_is_meaningful instead of
	breakpoint_address_is_meaningful.
	(bp_locations_compare): Adjust comment.
	(update_global_location_list): Use bl_address_is_meaningful
	instead of breakpoint_address_is_meaningful.
	* breakpoint.h (bp_location::bp_location(breakpoint *)): New
	explicit.
	(bp_location::bp_location(breakpoint *, bp_loc_type)): Declare.
	* python/py-breakpoint.c (bppy_get_location): No longer check
	whether location is null.

gdb/doc/ChangeLog:
2019-07-09  Pedro Alves  <palves@redhat.com>

	* gdb.texinfo (C++ Exception GDB/MI Catchpoint Commands): Adjust
	examples to show type=catchpoint instead of type=breakpoint and an
	address.

gdb/testsuite/ChangeLog:
2019-07-09  Pedro Alves  <palves@redhat.com>

	* gdb.cp/catch-multi-stdlib.exp: Adjust expected "info
	breakpoints" output.
	* gdb.cp/exception.exp: Adjust expected "info breakpoints" output.
	* gdb.python/py-breakpoint.exp: No longer expect that "catch
	throw" creates breakpoint.
	* gdb.mi/mi-catch-cpp-exceptions.exp (setup_catchpoint): Expect
	'type="catchpoint"'.
This commit is contained in:
Pedro Alves 2019-07-09 19:26:16 +01:00
parent b58a68fe57
commit cb1e4e32c2
12 changed files with 141 additions and 103 deletions

View file

@ -1,3 +1,34 @@
2019-07-09 Pedro Alves <palves@redhat.com>
* break-catch-throw.c (print_one_exception_catchpoint): Skip the
"addr" field.
(allocate_location_exception_catchpoint): New.
(handle_gnu_v3_exceptions): Don't reset 'type' to bp_breakpoint.
(initialize_throw_catchpoint_ops): Install
allocate_location_exception_catchpoint as allocate_location
method.
* breakpoint.c (bpstat_what) <bp_catch>: Set action to
BPSTAT_WHAT_SINGLE if not stopping and the location's type is not
bp_loc_other.
(breakpoint_address_is_meaningful): Delete.
(bl_address_is_meaningful): New.
(breakpoint_locations_match): Adjust comment.
(bp_location_from_bp_type): New, factored out of...
(bp_location::bp_location(breakpoint *)): ... this.
(bp_location::bp_location(breakpoint *, bp_loc_type)): New,
factored out of...
(bp_location::bp_location(breakpoint *)): ... this. Reimplement.
(bp_loc_is_permanent): Use bl_address_is_meaningful instead of
breakpoint_address_is_meaningful.
(bp_locations_compare): Adjust comment.
(update_global_location_list): Use bl_address_is_meaningful
instead of breakpoint_address_is_meaningful.
* breakpoint.h (bp_location::bp_location(breakpoint *)): New
explicit.
(bp_location::bp_location(breakpoint *, bp_loc_type)): Declare.
* python/py-breakpoint.c (bppy_get_location): No longer check
whether location is null.
2019-07-09 Pedro Alves <palves@redhat.com> 2019-07-09 Pedro Alves <palves@redhat.com>
PR c++/15468 PR c++/15468

View file

@ -249,18 +249,10 @@ print_one_exception_catchpoint (struct breakpoint *b,
enum exception_event_kind kind = classify_exception_breakpoint (b); enum exception_event_kind kind = classify_exception_breakpoint (b);
get_user_print_options (&opts); get_user_print_options (&opts);
if (opts.addressprint) if (opts.addressprint)
{ uiout->field_skip ("addr");
annotate_field (4);
if (b->loc == NULL || b->loc->shlib_disabled)
uiout->field_string ("addr", "<PENDING>");
else
uiout->field_core_addr ("addr",
b->loc->gdbarch, b->loc->address);
}
annotate_field (5); annotate_field (5);
if (b->loc)
*last_loc = b->loc;
switch (kind) switch (kind)
{ {
@ -344,6 +336,15 @@ print_recreate_exception_catchpoint (struct breakpoint *b,
print_recreate_thread (b, fp); print_recreate_thread (b, fp);
} }
/* Implement the "allocate_location" breakpoint_ops method for throw
and catch catchpoints. */
static bp_location *
allocate_location_exception_catchpoint (breakpoint *self)
{
return new bp_location (self, bp_loc_software_breakpoint);
}
static void static void
handle_gnu_v3_exceptions (int tempflag, std::string &&except_rx, handle_gnu_v3_exceptions (int tempflag, std::string &&except_rx,
const char *cond_string, const char *cond_string,
@ -361,9 +362,6 @@ handle_gnu_v3_exceptions (int tempflag, std::string &&except_rx,
init_catchpoint (cp.get (), get_current_arch (), tempflag, cond_string, init_catchpoint (cp.get (), get_current_arch (), tempflag, cond_string,
&gnu_v3_exception_catchpoint_ops); &gnu_v3_exception_catchpoint_ops);
/* We need to reset 'type' in order for code in breakpoint.c to do
the right thing. */
cp->type = bp_breakpoint;
cp->kind = ex_event; cp->kind = ex_event;
cp->exception_rx = std::move (except_rx); cp->exception_rx = std::move (except_rx);
cp->pattern = std::move (pattern); cp->pattern = std::move (pattern);
@ -521,6 +519,7 @@ initialize_throw_catchpoint_ops (void)
ops->print_recreate = print_recreate_exception_catchpoint; ops->print_recreate = print_recreate_exception_catchpoint;
ops->print_one_detail = print_one_detail_exception_catchpoint; ops->print_one_detail = print_one_detail_exception_catchpoint;
ops->check_status = check_status_exception_catchpoint; ops->check_status = check_status_exception_catchpoint;
ops->allocate_location = allocate_location_exception_catchpoint;
} }
void void

View file

@ -5603,8 +5603,10 @@ bpstat_what (bpstat bs_head)
} }
else else
{ {
/* There was a catchpoint, but we're not stopping. /* Some catchpoints are implemented with breakpoints.
This requires no further action. */ For those, we need to step over the breakpoint. */
if (bs->bp_location_at->loc_type != bp_loc_other)
this_action = BPSTAT_WHAT_SINGLE;
} }
break; break;
case bp_jit_event: case bp_jit_event:
@ -6686,27 +6688,21 @@ describe_other_breakpoints (struct gdbarch *gdbarch,
} }
/* Return true iff it is meaningful to use the address member of /* Return true iff it is meaningful to use the address member of LOC.
BPT locations. For some breakpoint types, the locations' address members For some breakpoint types, the locations' address members are
are irrelevant and it makes no sense to attempt to compare them to other irrelevant and it makes no sense to attempt to compare them to
addresses (or use them for any other purpose either). other addresses (or use them for any other purpose either).
More specifically, each of the following breakpoint types will More specifically, software watchpoints and catchpoints that are
always have a zero valued location address and we don't want to mark not backed by breakpoints always have a zero valued location
breakpoints of any of these types to be a duplicate of an actual address and we don't want to mark breakpoints of any of these types
breakpoint location at address zero: to be a duplicate of an actual breakpoint location at address
zero. */
bp_watchpoint static bool
bp_catchpoint bl_address_is_meaningful (bp_location *loc)
*/
static int
breakpoint_address_is_meaningful (struct breakpoint *bpt)
{ {
enum bptype type = bpt->type; return loc->loc_type != bp_loc_other;
return (type != bp_watchpoint && type != bp_catchpoint);
} }
/* Assuming LOC1 and LOC2's owners are hardware watchpoints, returns /* Assuming LOC1 and LOC2's owners are hardware watchpoints, returns
@ -6838,8 +6834,8 @@ tracepoint_locations_match (struct bp_location *loc1,
} }
/* Assuming LOC1 and LOC2's types' have meaningful target addresses /* Assuming LOC1 and LOC2's types' have meaningful target addresses
(breakpoint_address_is_meaningful), returns true if LOC1 and LOC2 (bl_address_is_meaningful), returns true if LOC1 and LOC2 represent
represent the same location. */ the same location. */
static int static int
breakpoint_locations_match (struct bp_location *loc1, breakpoint_locations_match (struct bp_location *loc1,
@ -6937,16 +6933,10 @@ adjust_breakpoint_address (struct gdbarch *gdbarch,
} }
} }
bp_location::bp_location (breakpoint *owner) static bp_loc_type
bp_location_from_bp_type (bptype type)
{ {
bp_location *loc = this; switch (type)
loc->owner = owner;
loc->cond_bytecode = NULL;
loc->shlib_disabled = 0;
loc->enabled = 1;
switch (owner->type)
{ {
case bp_breakpoint: case bp_breakpoint:
case bp_single_step: case bp_single_step:
@ -6972,30 +6962,44 @@ bp_location::bp_location (breakpoint *owner)
case bp_gnu_ifunc_resolver: case bp_gnu_ifunc_resolver:
case bp_gnu_ifunc_resolver_return: case bp_gnu_ifunc_resolver_return:
case bp_dprintf: case bp_dprintf:
loc->loc_type = bp_loc_software_breakpoint; return bp_loc_software_breakpoint;
mark_breakpoint_location_modified (loc);
break;
case bp_hardware_breakpoint: case bp_hardware_breakpoint:
loc->loc_type = bp_loc_hardware_breakpoint; return bp_loc_hardware_breakpoint;
mark_breakpoint_location_modified (loc);
break;
case bp_hardware_watchpoint: case bp_hardware_watchpoint:
case bp_read_watchpoint: case bp_read_watchpoint:
case bp_access_watchpoint: case bp_access_watchpoint:
loc->loc_type = bp_loc_hardware_watchpoint; return bp_loc_hardware_watchpoint;
break;
case bp_watchpoint: case bp_watchpoint:
case bp_catchpoint: case bp_catchpoint:
case bp_tracepoint: case bp_tracepoint:
case bp_fast_tracepoint: case bp_fast_tracepoint:
case bp_static_tracepoint: case bp_static_tracepoint:
loc->loc_type = bp_loc_other; return bp_loc_other;
break;
default: default:
internal_error (__FILE__, __LINE__, _("unknown breakpoint type")); internal_error (__FILE__, __LINE__, _("unknown breakpoint type"));
} }
}
loc->refc = 1; bp_location::bp_location (breakpoint *owner, bp_loc_type type)
{
this->owner = owner;
this->cond_bytecode = NULL;
this->shlib_disabled = 0;
this->enabled = 1;
this->loc_type = type;
if (this->loc_type == bp_loc_software_breakpoint
|| this->loc_type == bp_loc_hardware_breakpoint)
mark_breakpoint_location_modified (this);
this->refc = 1;
}
bp_location::bp_location (breakpoint *owner)
: bp_location::bp_location (owner,
bp_location_from_bp_type (owner->type))
{
} }
/* Allocate a struct bp_location. */ /* Allocate a struct bp_location. */
@ -8639,11 +8643,12 @@ bp_loc_is_permanent (struct bp_location *loc)
{ {
gdb_assert (loc != NULL); gdb_assert (loc != NULL);
/* If we have a catchpoint or a watchpoint, just return 0. We should not /* If we have a non-breakpoint-backed catchpoint or a software
attempt to read from the addresses the locations of these breakpoint types watchpoint, just return 0. We should not attempt to read from
point to. program_breakpoint_here_p, below, will attempt to read the addresses the locations of these breakpoint types point to.
program_breakpoint_here_p, below, will attempt to read
memory. */ memory. */
if (!breakpoint_address_is_meaningful (loc->owner)) if (!bl_address_is_meaningful (loc))
return 0; return 0;
scoped_restore_current_pspace_and_thread restore_pspace_thread; scoped_restore_current_pspace_and_thread restore_pspace_thread;
@ -11451,10 +11456,9 @@ breakpoint_auto_delete (bpstat bs)
/* A comparison function for bp_location AP and BP being interfaced to /* A comparison function for bp_location AP and BP being interfaced to
qsort. Sort elements primarily by their ADDRESS (no matter what qsort. Sort elements primarily by their ADDRESS (no matter what
does breakpoint_address_is_meaningful say for its OWNER), bl_address_is_meaningful says), secondarily by ordering first
secondarily by ordering first permanent elements and permanent elements and terciarily just ensuring the array is sorted
terciarily just ensuring the array is sorted stable way despite stable way despite qsort being an unstable algorithm. */
qsort being an unstable algorithm. */
static int static int
bp_locations_compare (const void *ap, const void *bp) bp_locations_compare (const void *ap, const void *bp)
@ -11794,7 +11798,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
this one from the target. */ this one from the target. */
/* OLD_LOC comes from existing struct breakpoint. */ /* OLD_LOC comes from existing struct breakpoint. */
if (breakpoint_address_is_meaningful (old_loc->owner)) if (bl_address_is_meaningful (old_loc))
{ {
for (loc2p = locp; for (loc2p = locp;
(loc2p < bp_locations + bp_locations_count (loc2p < bp_locations + bp_locations_count
@ -11934,7 +11938,7 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
b = loc->owner; b = loc->owner;
if (!unduplicated_should_be_inserted (loc) if (!unduplicated_should_be_inserted (loc)
|| !breakpoint_address_is_meaningful (b) || !bl_address_is_meaningful (loc)
/* Don't detect duplicate for tracepoint locations because they are /* Don't detect duplicate for tracepoint locations because they are
never duplicated. See the comments in field `duplicate' of never duplicated. See the comments in field `duplicate' of
`struct bp_location'. */ `struct bp_location'. */

View file

@ -316,7 +316,12 @@ class bp_location
public: public:
bp_location () = default; bp_location () = default;
bp_location (breakpoint *owner); /* Construct a bp_location with the type inferred from OWNER's
type. */
explicit bp_location (breakpoint *owner);
/* Construct a bp_location with type TYPE. */
bp_location (breakpoint *owner, bp_loc_type type);
virtual ~bp_location (); virtual ~bp_location ();

View file

@ -1,3 +1,9 @@
2019-07-09 Pedro Alves <palves@redhat.com>
* gdb.texinfo (C++ Exception GDB/MI Catchpoint Commands): Adjust
examples to show type=catchpoint instead of type=breakpoint and an
address.
2019-07-03 Pedro Alves <palves@redhat.com> 2019-07-03 Pedro Alves <palves@redhat.com>
Philippe Waroquiers <philippe.waroquiers@skynet.be> Philippe Waroquiers <philippe.waroquiers@skynet.be>

View file

@ -30120,9 +30120,9 @@ and @samp{tcatch throw} (@pxref{Set Catchpoints}).
@smallexample @smallexample
-catch-throw -r exception_type -catch-throw -r exception_type
^done,bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", ^done,bkpt=@{number="1",type="catchpoint",disp="keep",enabled="y",
addr="0x00000000004006c0",what="exception throw", what="exception throw",catch-type="throw",
catch-type="throw",thread-groups=["i1"], thread-groups=["i1"],
regexp="exception_type",times="0"@} regexp="exception_type",times="0"@}
(gdb) (gdb)
-exec-run -exec-run
@ -30164,9 +30164,9 @@ and @samp{tcatch rethrow} (@pxref{Set Catchpoints}).
@smallexample @smallexample
-catch-rethrow -r exception_type -catch-rethrow -r exception_type
^done,bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", ^done,bkpt=@{number="1",type="catchpoint",disp="keep",enabled="y",
addr="0x00000000004006c0",what="exception rethrow", what="exception rethrow",catch-type="rethrow",
catch-type="rethrow",thread-groups=["i1"], thread-groups=["i1"],
regexp="exception_type",times="0"@} regexp="exception_type",times="0"@}
(gdb) (gdb)
-exec-run -exec-run
@ -30208,9 +30208,9 @@ and @samp{tcatch catch} (@pxref{Set Catchpoints}).
@smallexample @smallexample
-catch-catch -r exception_type -catch-catch -r exception_type
^done,bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y", ^done,bkpt=@{number="1",type="catchpoint",disp="keep",enabled="y",
addr="0x00000000004006c0",what="exception catch", what="exception catch",catch-type="catch",
catch-type="catch",thread-groups=["i1"], thread-groups=["i1"],
regexp="exception_type",times="0"@} regexp="exception_type",times="0"@}
(gdb) (gdb)
-exec-run -exec-run

View file

@ -379,7 +379,6 @@ bppy_set_hit_count (PyObject *self, PyObject *newvalue, void *closure)
static PyObject * static PyObject *
bppy_get_location (PyObject *self, void *closure) bppy_get_location (PyObject *self, void *closure)
{ {
const char *str;
gdbpy_breakpoint_object *obj = (gdbpy_breakpoint_object *) self; gdbpy_breakpoint_object *obj = (gdbpy_breakpoint_object *) self;
BPPY_REQUIRE_VALID (obj); BPPY_REQUIRE_VALID (obj);
@ -387,12 +386,7 @@ bppy_get_location (PyObject *self, void *closure)
if (obj->bp->type != bp_breakpoint) if (obj->bp->type != bp_breakpoint)
Py_RETURN_NONE; Py_RETURN_NONE;
struct event_location *location = obj->bp->location.get (); const char *str = event_location_to_string (obj->bp->location.get ());
/* "catch throw" makes a breakpoint of type bp_breakpoint that does
not have a location. */
if (location == nullptr)
Py_RETURN_NONE;
str = event_location_to_string (location);
if (! str) if (! str)
str = ""; str = "";
return host_string_to_python_string (str).release (); return host_string_to_python_string (str).release ();

View file

@ -1,3 +1,13 @@
2019-07-09 Pedro Alves <palves@redhat.com>
* gdb.cp/catch-multi-stdlib.exp: Adjust expected "info
breakpoints" output.
* gdb.cp/exception.exp: Adjust expected "info breakpoints" output.
* gdb.python/py-breakpoint.exp: No longer expect that "catch
throw" creates breakpoint.
* gdb.mi/mi-catch-cpp-exceptions.exp (setup_catchpoint): Expect
'type="catchpoint"'.
2019-07-09 Pedro Alves <palves@redhat.com> 2019-07-09 Pedro Alves <palves@redhat.com>
PR c++/15468 PR c++/15468

View file

@ -74,9 +74,9 @@ proc test_multi_libstdcpp {static_bin static_lib} {
set ws "\[ \t\]*" set ws "\[ \t\]*"
gdb_test "info breakpoints" \ gdb_test "info breakpoints" \
[multi_line \ [multi_line \
"${decimal}${ws}breakpoint${ws}keep${ws}y${ws}${hex}${ws}exception catch" \ "${decimal}${ws}catchpoint${ws}keep${ws}y${ws}exception catch" \
"${decimal}${ws}breakpoint${ws}keep${ws}y${ws}${hex}${ws}exception throw" \ "${decimal}${ws}catchpoint${ws}keep${ws}y${ws}exception throw" \
"${decimal}${ws}breakpoint${ws}keep${ws}y${ws}${hex}${ws}exception rethrow"] "${decimal}${ws}catchpoint${ws}keep${ws}y${ws}exception rethrow"]
} }
# Try different static/not-static combinations. # Try different static/not-static combinations.

View file

@ -62,16 +62,10 @@ gdb_test "catch rethrow" "Catchpoint \[0-9\]+ \\(rethrow\\)" \
"catch rethrow (before inferior run)" "catch rethrow (before inferior run)"
# The catchpoints should be listed in the list of breakpoints.
# In case of a statically linked test, we won't have a pending breakpoint.
# Hence we allow for both an address or "<PENDING>". If we ever become able
# to tell whether the target is linked statically or not, we can be more
# precise and require exact output.
set addr "\(<PENDING>|$hex\)"
set re_head "Num${ws}Type${ws}Disp${ws}Enb${ws}Address${ws}What" set re_head "Num${ws}Type${ws}Disp${ws}Enb${ws}Address${ws}What"
set re_2_bp "1${ws}breakpoint${ws}keep${ws}y${ws}$addr${ws}exception catch" set re_2_bp "1${ws}catchpoint${ws}keep${ws}y${ws}exception catch"
set re_3_bp "2${ws}breakpoint${ws}keep${ws}y${ws}$addr${ws}exception throw" set re_3_bp "2${ws}catchpoint${ws}keep${ws}y${ws}exception throw"
set re_4_bp "3${ws}breakpoint${ws}keep${ws}y${ws}$addr${ws}exception rethrow" set re_4_bp "3${ws}catchpoint${ws}keep${ws}y${ws}exception rethrow"
set name "info breakpoints (before inferior run)" set name "info breakpoints (before inferior run)"
gdb_test_multiple "info breakpoints" $name { gdb_test_multiple "info breakpoints" $name {
@ -100,12 +94,6 @@ if { !$ok } {
continue continue
} }
set addr "$hex"
set re_head "Num${ws}Type${ws}Disp${ws}Enb${ws}Address${ws}What"
set re_2_bp "1${ws}breakpoint${ws}keep${ws}y${ws}$addr${ws}exception catch"
set re_3_bp "2${ws}breakpoint${ws}keep${ws}y${ws}$addr${ws}exception throw"
set re_4_bp "3${ws}breakpoint${ws}keep${ws}y${ws}$addr${ws}exception rethrow"
set name "info breakpoints (after inferior run)" set name "info breakpoints (after inferior run)"
gdb_test_multiple "info breakpoints" $name { gdb_test_multiple "info breakpoints" $name {
-re "$re_head${ws}$re_2_bp${ws}$re_3_bp${ws}$re_4_bp\r\n$gdb_prompt $" { -re "$re_head${ws}$re_2_bp${ws}$re_3_bp${ws}$re_4_bp\r\n$gdb_prompt $" {

View file

@ -85,7 +85,7 @@ proc continue_to_breakpoint_in_main {} {
proc setup_catchpoint {type {extra ""}} { proc setup_catchpoint {type {extra ""}} {
global decimal global decimal
mi_gdb_test "-catch-${type} ${extra}" \ mi_gdb_test "-catch-${type} ${extra}" \
"\\^done,bkpt=\{number=\"$decimal\".*what=\"exception ${type}\",catch-type=\"${type}\".*\}" \ "\\^done,bkpt=\{number=\"$decimal\",type=\"catchpoint\".*what=\"exception ${type}\",catch-type=\"${type}\".*\}" \
"Setup -catch-${type}" "Setup -catch-${type}"
} }

View file

@ -619,8 +619,9 @@ proc_with_prefix test_bkpt_explicit_loc {} {
delete_breakpoints delete_breakpoints
gdb_test "catch throw" "Catchpoint .* \\(throw\\)" gdb_test "catch throw" "Catchpoint .* \\(throw\\)"
gdb_test "python print (gdb.breakpoints()\[0\].location)" None \ gdb_test "python print (gdb.breakpoints())" \
"Examine location of catchpoint" "\(\)" \
"catch throw is not a breakpoint"
} }
proc_with_prefix test_bkpt_qualified {} { proc_with_prefix test_bkpt_qualified {} {