Skip to content
Snippets Groups Projects
  • Pedro Alves's avatar
    cb1e4e32
    "catch catch/throw/rethrow", breakpoint -> catchpoint · cb1e4e32
    Pedro Alves authored
    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 2a8be203
      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"'.
    cb1e4e32
    History
    "catch catch/throw/rethrow", breakpoint -> catchpoint
    Pedro Alves authored
    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 2a8be203
      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"'.