C++ify breakpoint class hierarchy (destructors only)
Breakpoints are currently in a limbo state between C and C++. There is a pseudo class hierarchy implemented using struct fields. Taking watchpoint as an example: struct watchpoint { /* The base class. */ struct breakpoint base; ... } and it is instantianted with "new watchpoint ()". When destroyed, a destructor is first invoked through the breakpoint_ops, and then the memory is freed by calling delete through a pointer to breakpoint. Address sanitizer complains about this, for example, because we new and delete the same memory using different types. This patch takes the logical step of making breakpoint subclasses extend the breakpoint class for real, and converts their destructors to actual C++ destructors. Regtested on the buildbot. gdb/ChangeLog: * breakpoint.h (struct breakpoint_ops) <dtor>: Remove. (struct breakpoint) <~breakpoint>: New. (struct watchpoint): Inherit from breakpoint. <~watchpoint>: New. <base>: Remove. (struct tracepoint): Inherit from breakpoint. <base>: Remove. * breakpoint.c (longjmp_breakpoint_ops): Remove. (struct longjmp_breakpoint): Inherit from breakpoint. <~longjmp_breakpoint>: New. <base>: Remove. (new_breakpoint_from_type): Remove casts. (watchpoint_in_thread_scope): Remove reference to base field. (watchpoint_del_at_next_stop): Likewise. (update_watchpoint): Likewise. (watchpoint_check): Likewise. (bpstat_check_watchpoint): Likewise. (set_longjmp_breakpoint): Likewise. (struct fork_catchpoint): Inherit from breakpoint. <base>: Remove. (struct solib_catchpoint): Inherit from breakpoint. <~solib_catchpoint>: New. <base>: Remove. (dtor_catch_solib): Change to ... (solib_catchpoint::~solib_catchpoint): ... this. (breakpoint_hit_catch_solib): Remove reference to base field. (add_solib_catchpoint): Likewise. (create_fork_vfork_event_catchpoint): Likewise. (struct exec_catchpoint): Inherit from breakpoint. <~exec_catchpoint>: New. <base>: Remove. (dtor_catch_exec): Change to ... (exec_catchpoint::~exec_catchpoint): ... this. (dtor_watchpoint): Change to ... (watchpoint::~watchpoint): ... this. (watch_command_1): Remove reference to base field. (catch_exec_command_1): Likewise. (base_breakpoint_dtor): Change to ... (breakpoint::~breakpoint): ... this. (base_breakpoint_ops): Remove dtor field value. (longjmp_bkpt_dtor): Change to ... (longjmp_breakpoint::~longjmp_breakpoint): ... this. (strace_marker_create_breakpoints_sal): Remove reference to base field. (delete_breakpoint): Don't manually call breakpoint destructor. (create_tracepoint_from_upload): Remove reference to base field. (trace_pass_set_count): Likewise. (initialize_breakpoint_ops): Don't initialize momentary_breakpoint_ops, don't set dtors. * ada-lang.c (struct ada_catchpoint): Inherit from breakpoint. <~ada_catchpoint>: New. <base>: Remove. (create_excep_cond_exprs): Remove reference to base field. (dtor_exception): Change to ... (ada_catchpoint::~ada_catchpoint): ... this. (dtor_catch_exception): Remove. (dtor_catch_exception_unhandled): Remove. (dtor_catch_assert): Remove. (create_ada_exception_catchpoint): Remove reference to base field. (initialize_ada_catchpoint_ops): Don't set dtors. * break-catch-sig.c (struct signal_catchpoint): Inherit from breakpoint. <~signal_catchpoint>: New. <base>: Remove. (signal_catchpoint_dtor): Change to ... (signal_catchpoint::~signal_catchpoint): ... this. (create_signal_catchpoint): Remove reference to base field. (initialize_signal_catchpoint_ops): Don't set dtor. * break-catch-syscall.c (struct syscall_catchpoint): Inherit from breakpoint. <~syscall_catchpoint>: New. <base>: Remove. (dtor_catch_syscall): Change to ... (syscall_catchpoint::~syscall_catchpoint): ... this. (create_syscall_event_catchpoint): Remove reference to base field. (initialize_syscall_catchpoint_ops): Don't set dtor. * break-catch-throw.c (struct exception_catchpoint): Inherit from breakpoint. <~exception_catchpoint>: New. <base>: Remove. (dtor_exception_catchpoint): Change to ... (exception_catchpoint::~exception_catchpoint): ... this. (handle_gnu_v3_exceptions): Remove reference to base field. (initialize_throw_catchpoint_ops): Don't set dtor. * ctf.c (ctf_get_traceframe_address): Remove reference to base field. * remote.c (remote_get_tracepoint_status): Likewise. * tracefile-tfile.c (tfile_get_traceframe_address): Likewise. * tracefile.c (tracefile_fetch_registers): Likewise. * tracepoint.c (actions_command): Likewise. (validate_actionline): Likewise. (tfind_1): Likewise. (get_traceframe_location): Likewise. (find_matching_tracepoint_location): Likewise. (parse_tracepoint_status): Likewise. * mi/mi-cmd-break.c (mi_cmd_break_passcount): Likewise.
This commit is contained in:
parent
3b0871f44a
commit
c1fc265720
101
gdb/ChangeLog
101
gdb/ChangeLog
@ -1,3 +1,104 @@
|
||||
2017-06-02 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
* breakpoint.h (struct breakpoint_ops) <dtor>: Remove.
|
||||
(struct breakpoint) <~breakpoint>: New.
|
||||
(struct watchpoint): Inherit from breakpoint.
|
||||
<~watchpoint>: New.
|
||||
<base>: Remove.
|
||||
(struct tracepoint): Inherit from breakpoint.
|
||||
<base>: Remove.
|
||||
* breakpoint.c (longjmp_breakpoint_ops): Remove.
|
||||
(struct longjmp_breakpoint): Inherit from breakpoint.
|
||||
<~longjmp_breakpoint>: New.
|
||||
<base>: Remove.
|
||||
(new_breakpoint_from_type): Remove casts.
|
||||
(watchpoint_in_thread_scope): Remove reference to base field.
|
||||
(watchpoint_del_at_next_stop): Likewise.
|
||||
(update_watchpoint): Likewise.
|
||||
(watchpoint_check): Likewise.
|
||||
(bpstat_check_watchpoint): Likewise.
|
||||
(set_longjmp_breakpoint): Likewise.
|
||||
(struct fork_catchpoint): Inherit from breakpoint.
|
||||
<base>: Remove.
|
||||
(struct solib_catchpoint): Inherit from breakpoint.
|
||||
<~solib_catchpoint>: New.
|
||||
<base>: Remove.
|
||||
(dtor_catch_solib): Change to ...
|
||||
(solib_catchpoint::~solib_catchpoint): ... this.
|
||||
(breakpoint_hit_catch_solib): Remove reference to base field.
|
||||
(add_solib_catchpoint): Likewise.
|
||||
(create_fork_vfork_event_catchpoint): Likewise.
|
||||
(struct exec_catchpoint): Inherit from breakpoint.
|
||||
<~exec_catchpoint>: New.
|
||||
<base>: Remove.
|
||||
(dtor_catch_exec): Change to ...
|
||||
(exec_catchpoint::~exec_catchpoint): ... this.
|
||||
(dtor_watchpoint): Change to ...
|
||||
(watchpoint::~watchpoint): ... this.
|
||||
(watch_command_1): Remove reference to base field.
|
||||
(catch_exec_command_1): Likewise.
|
||||
(base_breakpoint_dtor): Change to ...
|
||||
(breakpoint::~breakpoint): ... this.
|
||||
(base_breakpoint_ops): Remove dtor field value.
|
||||
(longjmp_bkpt_dtor): Change to ...
|
||||
(longjmp_breakpoint::~longjmp_breakpoint): ... this.
|
||||
(strace_marker_create_breakpoints_sal): Remove reference to base
|
||||
field.
|
||||
(delete_breakpoint): Don't manually call breakpoint destructor.
|
||||
(create_tracepoint_from_upload): Remove reference to base field.
|
||||
(trace_pass_set_count): Likewise.
|
||||
(initialize_breakpoint_ops): Don't initialize
|
||||
momentary_breakpoint_ops, don't set dtors.
|
||||
* ada-lang.c (struct ada_catchpoint): Inherit from breakpoint.
|
||||
<~ada_catchpoint>: New.
|
||||
<base>: Remove.
|
||||
(create_excep_cond_exprs): Remove reference to base field.
|
||||
(dtor_exception): Change to ...
|
||||
(ada_catchpoint::~ada_catchpoint): ... this.
|
||||
(dtor_catch_exception): Remove.
|
||||
(dtor_catch_exception_unhandled): Remove.
|
||||
(dtor_catch_assert): Remove.
|
||||
(create_ada_exception_catchpoint): Remove reference to base
|
||||
field.
|
||||
(initialize_ada_catchpoint_ops): Don't set dtors.
|
||||
* break-catch-sig.c (struct signal_catchpoint): Inherit from
|
||||
breakpoint.
|
||||
<~signal_catchpoint>: New.
|
||||
<base>: Remove.
|
||||
(signal_catchpoint_dtor): Change to ...
|
||||
(signal_catchpoint::~signal_catchpoint): ... this.
|
||||
(create_signal_catchpoint): Remove reference to base field.
|
||||
(initialize_signal_catchpoint_ops): Don't set dtor.
|
||||
* break-catch-syscall.c (struct syscall_catchpoint): Inherit
|
||||
from breakpoint.
|
||||
<~syscall_catchpoint>: New.
|
||||
<base>: Remove.
|
||||
(dtor_catch_syscall): Change to ...
|
||||
(syscall_catchpoint::~syscall_catchpoint): ... this.
|
||||
(create_syscall_event_catchpoint): Remove reference to base
|
||||
field.
|
||||
(initialize_syscall_catchpoint_ops): Don't set dtor.
|
||||
* break-catch-throw.c (struct exception_catchpoint): Inherit
|
||||
from breakpoint.
|
||||
<~exception_catchpoint>: New.
|
||||
<base>: Remove.
|
||||
(dtor_exception_catchpoint): Change to ...
|
||||
(exception_catchpoint::~exception_catchpoint): ... this.
|
||||
(handle_gnu_v3_exceptions): Remove reference to base field.
|
||||
(initialize_throw_catchpoint_ops): Don't set dtor.
|
||||
* ctf.c (ctf_get_traceframe_address): Remove reference to base
|
||||
field.
|
||||
* remote.c (remote_get_tracepoint_status): Likewise.
|
||||
* tracefile-tfile.c (tfile_get_traceframe_address): Likewise.
|
||||
* tracefile.c (tracefile_fetch_registers): Likewise.
|
||||
* tracepoint.c (actions_command): Likewise.
|
||||
(validate_actionline): Likewise.
|
||||
(tfind_1): Likewise.
|
||||
(get_traceframe_location): Likewise.
|
||||
(find_matching_tracepoint_location): Likewise.
|
||||
(parse_tracepoint_status): Likewise.
|
||||
* mi/mi-cmd-break.c (mi_cmd_break_passcount): Likewise.
|
||||
|
||||
2017-06-02 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
* breakpoint.c (struct longjmp_breakpoint): New struct.
|
||||
|
@ -12257,14 +12257,11 @@ static const struct bp_location_ops ada_catchpoint_location_ops =
|
||||
ada_catchpoint_location_dtor
|
||||
};
|
||||
|
||||
/* An instance of this type is used to represent an Ada catchpoint.
|
||||
It includes a "struct breakpoint" as a kind of base class; users
|
||||
downcast to "struct breakpoint *" when needed. */
|
||||
/* An instance of this type is used to represent an Ada catchpoint. */
|
||||
|
||||
struct ada_catchpoint
|
||||
struct ada_catchpoint : public breakpoint
|
||||
{
|
||||
/* The base class. */
|
||||
struct breakpoint base;
|
||||
~ada_catchpoint () override;
|
||||
|
||||
/* The name of the specific exception the user specified. */
|
||||
char *excep_string;
|
||||
@ -12285,7 +12282,7 @@ create_excep_cond_exprs (struct ada_catchpoint *c)
|
||||
return;
|
||||
|
||||
/* Same if there are no locations... */
|
||||
if (c->base.loc == NULL)
|
||||
if (c->loc == NULL)
|
||||
return;
|
||||
|
||||
/* Compute the condition expression in text form, from the specific
|
||||
@ -12295,7 +12292,7 @@ create_excep_cond_exprs (struct ada_catchpoint *c)
|
||||
|
||||
/* Iterate over all the catchpoint's locations, and parse an
|
||||
expression for each. */
|
||||
for (bl = c->base.loc; bl != NULL; bl = bl->next)
|
||||
for (bl = c->loc; bl != NULL; bl = bl->next)
|
||||
{
|
||||
struct ada_catchpoint_location *ada_loc
|
||||
= (struct ada_catchpoint_location *) bl;
|
||||
@ -12316,7 +12313,7 @@ create_excep_cond_exprs (struct ada_catchpoint *c)
|
||||
{
|
||||
warning (_("failed to reevaluate internal exception condition "
|
||||
"for catchpoint %d: %s"),
|
||||
c->base.number, e.message);
|
||||
c->number, e.message);
|
||||
}
|
||||
END_CATCH
|
||||
}
|
||||
@ -12327,17 +12324,11 @@ create_excep_cond_exprs (struct ada_catchpoint *c)
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Implement the DTOR method in the breakpoint_ops structure for all
|
||||
exception catchpoint kinds. */
|
||||
/* ada_catchpoint destructor. */
|
||||
|
||||
static void
|
||||
dtor_exception (enum ada_exception_catchpoint_kind ex, struct breakpoint *b)
|
||||
ada_catchpoint::~ada_catchpoint ()
|
||||
{
|
||||
struct ada_catchpoint *c = (struct ada_catchpoint *) b;
|
||||
|
||||
xfree (c->excep_string);
|
||||
|
||||
bkpt_breakpoint_ops.dtor (b);
|
||||
xfree (this->excep_string);
|
||||
}
|
||||
|
||||
/* Implement the ALLOCATE_LOCATION method in the breakpoint_ops
|
||||
@ -12623,12 +12614,6 @@ print_recreate_exception (enum ada_exception_catchpoint_kind ex,
|
||||
|
||||
/* Virtual table for "catch exception" breakpoints. */
|
||||
|
||||
static void
|
||||
dtor_catch_exception (struct breakpoint *b)
|
||||
{
|
||||
dtor_exception (ada_catch_exception, b);
|
||||
}
|
||||
|
||||
static struct bp_location *
|
||||
allocate_location_catch_exception (struct breakpoint *self)
|
||||
{
|
||||
@ -12675,12 +12660,6 @@ static struct breakpoint_ops catch_exception_breakpoint_ops;
|
||||
|
||||
/* Virtual table for "catch exception unhandled" breakpoints. */
|
||||
|
||||
static void
|
||||
dtor_catch_exception_unhandled (struct breakpoint *b)
|
||||
{
|
||||
dtor_exception (ada_catch_exception_unhandled, b);
|
||||
}
|
||||
|
||||
static struct bp_location *
|
||||
allocate_location_catch_exception_unhandled (struct breakpoint *self)
|
||||
{
|
||||
@ -12729,12 +12708,6 @@ static struct breakpoint_ops catch_exception_unhandled_breakpoint_ops;
|
||||
|
||||
/* Virtual table for "catch assert" breakpoints. */
|
||||
|
||||
static void
|
||||
dtor_catch_assert (struct breakpoint *b)
|
||||
{
|
||||
dtor_exception (ada_catch_assert, b);
|
||||
}
|
||||
|
||||
static struct bp_location *
|
||||
allocate_location_catch_assert (struct breakpoint *self)
|
||||
{
|
||||
@ -13060,13 +13033,13 @@ create_ada_exception_catchpoint (struct gdbarch *gdbarch,
|
||||
= ada_exception_sal (ex_kind, excep_string, &addr_string, &ops);
|
||||
|
||||
c = new ada_catchpoint ();
|
||||
init_ada_exception_breakpoint (&c->base, gdbarch, sal, addr_string,
|
||||
init_ada_exception_breakpoint (c, gdbarch, sal, addr_string,
|
||||
ops, tempflag, disabled, from_tty);
|
||||
c->excep_string = excep_string;
|
||||
create_excep_cond_exprs (c);
|
||||
if (cond_string != NULL)
|
||||
set_breakpoint_condition (&c->base, cond_string, from_tty);
|
||||
install_breakpoint (0, &c->base, 1);
|
||||
set_breakpoint_condition (c, cond_string, from_tty);
|
||||
install_breakpoint (0, c, 1);
|
||||
}
|
||||
|
||||
/* Implement the "catch exception" command. */
|
||||
@ -14090,7 +14063,6 @@ initialize_ada_catchpoint_ops (void)
|
||||
|
||||
ops = &catch_exception_breakpoint_ops;
|
||||
*ops = bkpt_breakpoint_ops;
|
||||
ops->dtor = dtor_catch_exception;
|
||||
ops->allocate_location = allocate_location_catch_exception;
|
||||
ops->re_set = re_set_catch_exception;
|
||||
ops->check_status = check_status_catch_exception;
|
||||
@ -14101,7 +14073,6 @@ initialize_ada_catchpoint_ops (void)
|
||||
|
||||
ops = &catch_exception_unhandled_breakpoint_ops;
|
||||
*ops = bkpt_breakpoint_ops;
|
||||
ops->dtor = dtor_catch_exception_unhandled;
|
||||
ops->allocate_location = allocate_location_catch_exception_unhandled;
|
||||
ops->re_set = re_set_catch_exception_unhandled;
|
||||
ops->check_status = check_status_catch_exception_unhandled;
|
||||
@ -14112,7 +14083,6 @@ initialize_ada_catchpoint_ops (void)
|
||||
|
||||
ops = &catch_assert_breakpoint_ops;
|
||||
*ops = bkpt_breakpoint_ops;
|
||||
ops->dtor = dtor_catch_assert;
|
||||
ops->allocate_location = allocate_location_catch_assert;
|
||||
ops->re_set = re_set_catch_assert;
|
||||
ops->check_status = check_status_catch_assert;
|
||||
|
@ -38,16 +38,12 @@ typedef enum gdb_signal gdb_signal_type;
|
||||
DEF_VEC_I (gdb_signal_type);
|
||||
|
||||
/* An instance of this type is used to represent a signal catchpoint.
|
||||
It includes a "struct breakpoint" as a kind of base class; users
|
||||
downcast to "struct breakpoint *" when needed. A breakpoint is
|
||||
really of this type iff its ops pointer points to
|
||||
A breakpoint is really of this type iff its ops pointer points to
|
||||
SIGNAL_CATCHPOINT_OPS. */
|
||||
|
||||
struct signal_catchpoint
|
||||
struct signal_catchpoint : public breakpoint
|
||||
{
|
||||
/* The base class. */
|
||||
|
||||
struct breakpoint base;
|
||||
~signal_catchpoint () override;
|
||||
|
||||
/* Signal numbers used for the 'catch signal' feature. If no signal
|
||||
has been specified for filtering, its value is NULL. Otherwise,
|
||||
@ -89,17 +85,11 @@ signal_to_name_or_int (enum gdb_signal sig)
|
||||
|
||||
|
||||
|
||||
/* Implement the "dtor" breakpoint_ops method for signal
|
||||
catchpoints. */
|
||||
/* signal_catchpoint destructor. */
|
||||
|
||||
static void
|
||||
signal_catchpoint_dtor (struct breakpoint *b)
|
||||
signal_catchpoint::~signal_catchpoint ()
|
||||
{
|
||||
struct signal_catchpoint *c = (struct signal_catchpoint *) b;
|
||||
|
||||
VEC_free (gdb_signal_type, c->signals_to_be_caught);
|
||||
|
||||
base_breakpoint_ops.dtor (b);
|
||||
VEC_free (gdb_signal_type, this->signals_to_be_caught);
|
||||
}
|
||||
|
||||
/* Implement the "insert_location" breakpoint_ops method for signal
|
||||
@ -372,11 +362,11 @@ create_signal_catchpoint (int tempflag, VEC (gdb_signal_type) *filter,
|
||||
struct gdbarch *gdbarch = get_current_arch ();
|
||||
|
||||
c = new signal_catchpoint ();
|
||||
init_catchpoint (&c->base, gdbarch, tempflag, NULL, &signal_catchpoint_ops);
|
||||
init_catchpoint (c, gdbarch, tempflag, NULL, &signal_catchpoint_ops);
|
||||
c->signals_to_be_caught = filter;
|
||||
c->catch_all = catch_all;
|
||||
|
||||
install_breakpoint (0, &c->base, 1);
|
||||
install_breakpoint (0, c, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -473,7 +463,6 @@ initialize_signal_catchpoint_ops (void)
|
||||
|
||||
ops = &signal_catchpoint_ops;
|
||||
*ops = base_breakpoint_ops;
|
||||
ops->dtor = signal_catchpoint_dtor;
|
||||
ops->insert_location = signal_catchpoint_insert_location;
|
||||
ops->remove_location = signal_catchpoint_remove_location;
|
||||
ops->breakpoint_hit = signal_catchpoint_breakpoint_hit;
|
||||
|
@ -31,15 +31,12 @@
|
||||
#include "xml-syscall.h"
|
||||
|
||||
/* An instance of this type is used to represent a syscall catchpoint.
|
||||
It includes a "struct breakpoint" as a kind of base class; users
|
||||
downcast to "struct breakpoint *" when needed. A breakpoint is
|
||||
really of this type iff its ops pointer points to
|
||||
A breakpoint is really of this type iff its ops pointer points to
|
||||
CATCH_SYSCALL_BREAKPOINT_OPS. */
|
||||
|
||||
struct syscall_catchpoint
|
||||
struct syscall_catchpoint : public breakpoint
|
||||
{
|
||||
/* The base class. */
|
||||
struct breakpoint base;
|
||||
~syscall_catchpoint () override;
|
||||
|
||||
/* Syscall numbers used for the 'catch syscall' feature. If no
|
||||
syscall has been specified for filtering, its value is NULL.
|
||||
@ -48,17 +45,11 @@ struct syscall_catchpoint
|
||||
VEC(int) *syscalls_to_be_caught;
|
||||
};
|
||||
|
||||
/* Implement the "dtor" breakpoint_ops method for syscall
|
||||
catchpoints. */
|
||||
/* catch_syscall destructor. */
|
||||
|
||||
static void
|
||||
dtor_catch_syscall (struct breakpoint *b)
|
||||
syscall_catchpoint::~syscall_catchpoint ()
|
||||
{
|
||||
struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
|
||||
|
||||
VEC_free (int, c->syscalls_to_be_caught);
|
||||
|
||||
base_breakpoint_ops.dtor (b);
|
||||
VEC_free (int, this->syscalls_to_be_caught);
|
||||
}
|
||||
|
||||
static const struct inferior_data *catch_syscall_inferior_data = NULL;
|
||||
@ -434,10 +425,10 @@ create_syscall_event_catchpoint (int tempflag, VEC(int) *filter,
|
||||
struct gdbarch *gdbarch = get_current_arch ();
|
||||
|
||||
c = new syscall_catchpoint ();
|
||||
init_catchpoint (&c->base, gdbarch, tempflag, NULL, ops);
|
||||
init_catchpoint (c, gdbarch, tempflag, NULL, ops);
|
||||
c->syscalls_to_be_caught = filter;
|
||||
|
||||
install_breakpoint (0, &c->base, 1);
|
||||
install_breakpoint (0, c, 1);
|
||||
}
|
||||
|
||||
/* Splits the argument using space as delimiter. Returns an xmalloc'd
|
||||
@ -701,7 +692,6 @@ initialize_syscall_catchpoint_ops (void)
|
||||
/* Syscall catchpoints. */
|
||||
ops = &catch_syscall_breakpoint_ops;
|
||||
*ops = base_breakpoint_ops;
|
||||
ops->dtor = dtor_catch_syscall;
|
||||
ops->insert_location = insert_catch_syscall;
|
||||
ops->remove_location = remove_catch_syscall;
|
||||
ops->breakpoint_hit = breakpoint_hit_catch_syscall;
|
||||
|
@ -74,11 +74,9 @@ static struct breakpoint_ops gnu_v3_exception_catchpoint_ops;
|
||||
|
||||
/* The type of an exception catchpoint. */
|
||||
|
||||
struct exception_catchpoint
|
||||
struct exception_catchpoint : public breakpoint
|
||||
{
|
||||
/* The base class. */
|
||||
|
||||
struct breakpoint base;
|
||||
~exception_catchpoint () override;
|
||||
|
||||
/* The kind of exception catchpoint. */
|
||||
|
||||
@ -142,17 +140,13 @@ classify_exception_breakpoint (struct breakpoint *b)
|
||||
return cp->kind;
|
||||
}
|
||||
|
||||
/* Implement the 'dtor' method. */
|
||||
/* exception_catchpoint destructor. */
|
||||
|
||||
static void
|
||||
dtor_exception_catchpoint (struct breakpoint *self)
|
||||
exception_catchpoint::~exception_catchpoint ()
|
||||
{
|
||||
struct exception_catchpoint *cp = (struct exception_catchpoint *) self;
|
||||
|
||||
xfree (cp->exception_rx);
|
||||
if (cp->pattern != NULL)
|
||||
regfree (cp->pattern);
|
||||
bkpt_breakpoint_ops.dtor (self);
|
||||
xfree (this->exception_rx);
|
||||
if (this->pattern != NULL)
|
||||
regfree (this->pattern);
|
||||
}
|
||||
|
||||
/* Implement the 'check_status' method. */
|
||||
@ -396,18 +390,18 @@ handle_gnu_v3_exceptions (int tempflag, char *except_rx,
|
||||
|
||||
std::unique_ptr<exception_catchpoint> cp (new exception_catchpoint ());
|
||||
|
||||
init_catchpoint (&cp->base, get_current_arch (), tempflag, cond_string,
|
||||
init_catchpoint (cp.get (), get_current_arch (), tempflag, cond_string,
|
||||
&gnu_v3_exception_catchpoint_ops);
|
||||
/* We need to reset 'type' in order for code in breakpoint.c to do
|
||||
the right thing. */
|
||||
cp->base.type = bp_breakpoint;
|
||||
cp->type = bp_breakpoint;
|
||||
cp->kind = ex_event;
|
||||
cp->exception_rx = except_rx;
|
||||
cp->pattern = pattern;
|
||||
|
||||
re_set_exception_catchpoint (&cp->base);
|
||||
re_set_exception_catchpoint (cp.get ());
|
||||
|
||||
install_breakpoint (0, &cp->base, 1);
|
||||
install_breakpoint (0, cp.get (), 1);
|
||||
cp.release ();
|
||||
}
|
||||
|
||||
@ -558,7 +552,6 @@ initialize_throw_catchpoint_ops (void)
|
||||
/* GNU v3 exception catchpoints. */
|
||||
ops = &gnu_v3_exception_catchpoint_ops;
|
||||
*ops = bkpt_breakpoint_ops;
|
||||
ops->dtor = dtor_exception_catchpoint;
|
||||
ops->re_set = re_set_exception_catchpoint;
|
||||
ops->print_it = print_it_exception_catchpoint;
|
||||
ops->print_one = print_one_exception_catchpoint;
|
||||
|
257
gdb/breakpoint.c
257
gdb/breakpoint.c
@ -309,9 +309,6 @@ static struct breakpoint_ops internal_breakpoint_ops;
|
||||
/* Momentary breakpoints class type. */
|
||||
static struct breakpoint_ops momentary_breakpoint_ops;
|
||||
|
||||
/* Momentary breakpoints for bp_longjmp and bp_exception class type. */
|
||||
static struct breakpoint_ops longjmp_breakpoint_ops;
|
||||
|
||||
/* The breakpoint_ops structure to be used in regular user created
|
||||
breakpoints. */
|
||||
struct breakpoint_ops bkpt_breakpoint_ops;
|
||||
@ -1160,9 +1157,9 @@ check_no_tracepoint_commands (struct command_line *commands)
|
||||
}
|
||||
}
|
||||
|
||||
struct longjmp_breakpoint
|
||||
struct longjmp_breakpoint : public breakpoint
|
||||
{
|
||||
breakpoint base;
|
||||
~longjmp_breakpoint () override;
|
||||
};
|
||||
|
||||
/* Encapsulate tests for different types of tracepoints. */
|
||||
@ -1196,9 +1193,9 @@ new_breakpoint_from_type (bptype type)
|
||||
breakpoint *b;
|
||||
|
||||
if (is_tracepoint_type (type))
|
||||
b = (breakpoint *) new tracepoint ();
|
||||
b = new tracepoint ();
|
||||
else if (is_longjmp_type (type))
|
||||
b = (breakpoint *) new longjmp_breakpoint ();
|
||||
b = new longjmp_breakpoint ();
|
||||
else
|
||||
b = new breakpoint ();
|
||||
|
||||
@ -1736,7 +1733,7 @@ is_watchpoint (const struct breakpoint *bpt)
|
||||
static int
|
||||
watchpoint_in_thread_scope (struct watchpoint *b)
|
||||
{
|
||||
return (b->base.pspace == current_program_space
|
||||
return (b->pspace == current_program_space
|
||||
&& (ptid_equal (b->watchpoint_thread, null_ptid)
|
||||
|| (ptid_equal (inferior_ptid, b->watchpoint_thread)
|
||||
&& !is_executing (inferior_ptid))));
|
||||
@ -1748,17 +1745,15 @@ watchpoint_in_thread_scope (struct watchpoint *b)
|
||||
static void
|
||||
watchpoint_del_at_next_stop (struct watchpoint *w)
|
||||
{
|
||||
struct breakpoint *b = &w->base;
|
||||
|
||||
if (b->related_breakpoint != b)
|
||||
if (w->related_breakpoint != w)
|
||||
{
|
||||
gdb_assert (b->related_breakpoint->type == bp_watchpoint_scope);
|
||||
gdb_assert (b->related_breakpoint->related_breakpoint == b);
|
||||
b->related_breakpoint->disposition = disp_del_at_next_stop;
|
||||
b->related_breakpoint->related_breakpoint = b->related_breakpoint;
|
||||
b->related_breakpoint = b;
|
||||
gdb_assert (w->related_breakpoint->type == bp_watchpoint_scope);
|
||||
gdb_assert (w->related_breakpoint->related_breakpoint == w);
|
||||
w->related_breakpoint->disposition = disp_del_at_next_stop;
|
||||
w->related_breakpoint->related_breakpoint = w->related_breakpoint;
|
||||
w->related_breakpoint = w;
|
||||
}
|
||||
b->disposition = disp_del_at_next_stop;
|
||||
w->disposition = disp_del_at_next_stop;
|
||||
}
|
||||
|
||||
/* Extract a bitfield value from value VAL using the bit parameters contained in
|
||||
@ -1879,7 +1874,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
if (!watchpoint_in_thread_scope (b))
|
||||
return;
|
||||
|
||||
if (b->base.disposition == disp_del_at_next_stop)
|
||||
if (b->disposition == disp_del_at_next_stop)
|
||||
return;
|
||||
|
||||
frame_saved = 0;
|
||||
@ -1917,7 +1912,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
/* We don't free locations. They are stored in the bp_location array
|
||||
and update_global_location_list will eventually delete them and
|
||||
remove breakpoints if needed. */
|
||||
b->base.loc = NULL;
|
||||
b->loc = NULL;
|
||||
|
||||
if (within_current_scope && reparse)
|
||||
{
|
||||
@ -1937,11 +1932,11 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
/* Note that unlike with breakpoints, the watchpoint's condition
|
||||
expression is stored in the breakpoint object, not in the
|
||||
locations (re)created below. */
|
||||
if (b->base.cond_string != NULL)
|
||||
if (b->cond_string != NULL)
|
||||
{
|
||||
b->cond_exp.reset ();
|
||||
|
||||
s = b->base.cond_string;
|
||||
s = b->cond_string;
|
||||
b->cond_exp = parse_exp_1 (&s, 0, b->cond_exp_valid_block, 0);
|
||||
}
|
||||
}
|
||||
@ -1958,8 +1953,8 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
the target gains execution, through breakpoint_re_set. */
|
||||
if (!can_use_hw_watchpoints)
|
||||
{
|
||||
if (b->base.ops->works_in_software_mode (&b->base))
|
||||
b->base.type = bp_watchpoint;
|
||||
if (b->ops->works_in_software_mode (b))
|
||||
b->type = bp_watchpoint;
|
||||
else
|
||||
error (_("Can't set read/access watchpoint when "
|
||||
"hardware watchpoints are disabled."));
|
||||
@ -1979,7 +1974,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
happens, the code that reports it updates b->val directly.
|
||||
We don't keep track of the memory value for masked
|
||||
watchpoints. */
|
||||
if (!b->val_valid && !is_masked_watchpoint (&b->base))
|
||||
if (!b->val_valid && !is_masked_watchpoint (b))
|
||||
{
|
||||
if (b->val_bitsize != 0)
|
||||
{
|
||||
@ -2042,13 +2037,13 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
}
|
||||
|
||||
type = hw_write;
|
||||
if (b->base.type == bp_read_watchpoint)
|
||||
if (b->type == bp_read_watchpoint)
|
||||
type = hw_read;
|
||||
else if (b->base.type == bp_access_watchpoint)
|
||||
else if (b->type == bp_access_watchpoint)
|
||||
type = hw_access;
|
||||
|
||||
loc = allocate_bp_location (&b->base);
|
||||
for (tmp = &(b->base.loc); *tmp != NULL; tmp = &((*tmp)->next))
|
||||
loc = allocate_bp_location (b);
|
||||
for (tmp = &(b->loc); *tmp != NULL; tmp = &((*tmp)->next))
|
||||
;
|
||||
*tmp = loc;
|
||||
loc->gdbarch = get_type_arch (value_type (v));
|
||||
@ -2098,7 +2093,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
/* If this is a software watchpoint, we try to turn it
|
||||
to a hardware one -- count resources as if B was of
|
||||
hardware watchpoint type. */
|
||||
type = b->base.type;
|
||||
type = b->type;
|
||||
if (type == bp_watchpoint)
|
||||
type = bp_hardware_watchpoint;
|
||||
|
||||
@ -2109,16 +2104,16 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
manually. */
|
||||
|
||||
/* Count resources used by all watchpoints except B. */
|
||||
i = hw_watchpoint_used_count_others (&b->base, type, &other_type_used);
|
||||
i = hw_watchpoint_used_count_others (b, type, &other_type_used);
|
||||
|
||||
/* Add in the resources needed for B. */
|
||||
i += hw_watchpoint_use_count (&b->base);
|
||||
i += hw_watchpoint_use_count (b);
|
||||
|
||||
target_resources_ok
|
||||
= target_can_use_hardware_watchpoint (type, i, other_type_used);
|
||||
if (target_resources_ok <= 0)
|
||||
{
|
||||
int sw_mode = b->base.ops->works_in_software_mode (&b->base);
|
||||
int sw_mode = b->ops->works_in_software_mode (b);
|
||||
|
||||
if (target_resources_ok == 0 && !sw_mode)
|
||||
error (_("Target does not support this type of "
|
||||
@ -2128,7 +2123,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
"resources for this watchpoint."));
|
||||
|
||||
/* Downgrade to software watchpoint. */
|
||||
b->base.type = bp_watchpoint;
|
||||
b->type = bp_watchpoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2136,10 +2131,10 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
found we have enough resources to turn it to a
|
||||
hardware watchpoint. Otherwise, this is a
|
||||
nop. */
|
||||
b->base.type = type;
|
||||
b->type = type;
|
||||
}
|
||||
}
|
||||
else if (!b->base.ops->works_in_software_mode (&b->base))
|
||||
else if (!b->ops->works_in_software_mode (b))
|
||||
{
|
||||
if (!can_use_hw_watchpoints)
|
||||
error (_("Can't set read/access watchpoint when "
|
||||
@ -2149,11 +2144,11 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
"read/access watchpoint."));
|
||||
}
|
||||
else
|
||||
b->base.type = bp_watchpoint;
|
||||
b->type = bp_watchpoint;
|
||||
|
||||
loc_type = (b->base.type == bp_watchpoint? bp_loc_other
|
||||
loc_type = (b->type == bp_watchpoint? bp_loc_other
|
||||
: bp_loc_hardware_watchpoint);
|
||||
for (bl = b->base.loc; bl; bl = bl->next)
|
||||
for (bl = b->loc; bl; bl = bl->next)
|
||||
bl->loc_type = loc_type;
|
||||
}
|
||||
|
||||
@ -2168,15 +2163,15 @@ update_watchpoint (struct watchpoint *b, int reparse)
|
||||
above left it without any location set up. But,
|
||||
bpstat_stop_status requires a location to be able to report
|
||||
stops, so make sure there's at least a dummy one. */
|
||||
if (b->base.type == bp_watchpoint && b->base.loc == NULL)
|
||||
software_watchpoint_add_no_memory_location (&b->base, frame_pspace);
|
||||
if (b->type == bp_watchpoint && b->loc == NULL)
|
||||
software_watchpoint_add_no_memory_location (b, frame_pspace);
|
||||
}
|
||||
else if (!within_current_scope)
|
||||
{
|
||||
printf_filtered (_("\
|
||||
Watchpoint %d deleted because the program has left the block\n\
|
||||
in which its expression is valid.\n"),
|
||||
b->base.number);
|
||||
b->number);
|
||||
watchpoint_del_at_next_stop (b);
|
||||
}
|
||||
|
||||
@ -5196,7 +5191,7 @@ watchpoint_check (void *p)
|
||||
struct value *mark;
|
||||
struct value *new_val;
|
||||
|
||||
if (is_masked_watchpoint (&b->base))
|
||||
if (is_masked_watchpoint (b))
|
||||
/* Since we don't know the exact trigger address (from
|
||||
stopped_data_address), just tell the user we've triggered
|
||||
a mask watchpoint. */
|
||||
@ -5256,13 +5251,13 @@ watchpoint_check (void *p)
|
||||
uiout->field_string
|
||||
("reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE));
|
||||
uiout->text ("\nWatchpoint ");
|
||||
uiout->field_int ("wpnum", b->base.number);
|
||||
uiout->field_int ("wpnum", b->number);
|
||||
uiout->text (" deleted because the program has left the block in\n"
|
||||
"which its expression is valid.\n");
|
||||
}
|
||||
|
||||
/* Make sure the watchpoint's commands aren't executed. */
|
||||
decref_counted_command_line (&b->base.commands);
|
||||
decref_counted_command_line (&b->commands);
|
||||
watchpoint_del_at_next_stop (b);
|
||||
|
||||
return WP_DELETED;
|
||||
@ -5304,7 +5299,7 @@ bpstat_check_watchpoint (bpstat bs)
|
||||
{
|
||||
int must_check_value = 0;
|
||||
|
||||
if (b->base.type == bp_watchpoint)
|
||||
if (b->type == bp_watchpoint)
|
||||
/* For a software watchpoint, we must always check the
|
||||
watched value. */
|
||||
must_check_value = 1;
|
||||
@ -5314,7 +5309,7 @@ bpstat_check_watchpoint (bpstat bs)
|
||||
this watchpoint. */
|
||||
must_check_value = 1;
|
||||
else if (b->watchpoint_triggered == watch_triggered_unknown
|
||||
&& b->base.type == bp_hardware_watchpoint)
|
||||
&& b->type == bp_hardware_watchpoint)
|
||||
/* We were stopped by a hardware watchpoint, but the target could
|
||||
not report the data address. We must check the watchpoint's
|
||||
value. Access and read watchpoints are out of luck; without
|
||||
@ -5325,7 +5320,7 @@ bpstat_check_watchpoint (bpstat bs)
|
||||
{
|
||||
char *message
|
||||
= xstrprintf ("Error evaluating expression for watchpoint %d\n",
|
||||
b->base.number);
|
||||
b->number);
|
||||
struct cleanup *cleanups = make_cleanup (xfree, message);
|
||||
int e = catch_errors (watchpoint_check, bs, message,
|
||||
RETURN_MASK_ALL);
|
||||
@ -5342,7 +5337,7 @@ bpstat_check_watchpoint (bpstat bs)
|
||||
bs->stop = 0;
|
||||
break;
|
||||
case WP_VALUE_CHANGED:
|
||||
if (b->base.type == bp_read_watchpoint)
|
||||
if (b->type == bp_read_watchpoint)
|
||||
{
|
||||
/* There are two cases to consider here:
|
||||
|
||||
@ -5413,8 +5408,8 @@ bpstat_check_watchpoint (bpstat bs)
|
||||
}
|
||||
break;
|
||||
case WP_VALUE_NOT_CHANGED:
|
||||
if (b->base.type == bp_hardware_watchpoint
|
||||
|| b->base.type == bp_watchpoint)
|
||||
if (b->type == bp_hardware_watchpoint
|
||||
|| b->type == bp_watchpoint)
|
||||
{
|
||||
/* Don't stop: write watchpoints shouldn't fire if
|
||||
the value hasn't changed. */
|
||||
@ -5431,7 +5426,7 @@ bpstat_check_watchpoint (bpstat bs)
|
||||
SWITCH_THRU_ALL_UIS ()
|
||||
{
|
||||
printf_filtered (_("Watchpoint %d deleted.\n"),
|
||||
b->base.number);
|
||||
b->number);
|
||||
}
|
||||
watchpoint_del_at_next_stop (b);
|
||||
/* We've already printed what needs to be printed. */
|
||||
@ -7609,7 +7604,7 @@ set_longjmp_breakpoint (struct thread_info *tp, struct frame_id frame)
|
||||
/* longjmp_breakpoint_ops ensures INITIATING_FRAME is cleared again
|
||||
after their removal. */
|
||||
clone = momentary_breakpoint_from_master (b, type,
|
||||
&longjmp_breakpoint_ops, 1);
|
||||
&momentary_breakpoint_ops, 1);
|
||||
clone->thread = thread;
|
||||
}
|
||||
|
||||
@ -8031,16 +8026,11 @@ disable_breakpoints_in_freed_objfile (struct objfile *objfile)
|
||||
/* FORK & VFORK catchpoints. */
|
||||
|
||||
/* An instance of this type is used to represent a fork or vfork
|
||||
catchpoint. It includes a "struct breakpoint" as a kind of base
|
||||
class; users downcast to "struct breakpoint *" when needed. A
|
||||
breakpoint is really of this type iff its ops pointer points to
|
||||
CATCH_FORK_BREAKPOINT_OPS. */
|
||||
catchpoint. A breakpoint is really of this type iff its ops pointer points
|
||||
to CATCH_FORK_BREAKPOINT_OPS. */
|
||||
|
||||
struct fork_catchpoint
|
||||
struct fork_catchpoint : public breakpoint
|
||||
{
|
||||
/* The base class. */
|
||||
struct breakpoint base;
|
||||
|
||||
/* Process id of a child process whose forking triggered this
|
||||
catchpoint. This field is only valid immediately after this
|
||||
catchpoint has triggered. */
|
||||
@ -8279,15 +8269,12 @@ print_recreate_catch_vfork (struct breakpoint *b, struct ui_file *fp)
|
||||
static struct breakpoint_ops catch_vfork_breakpoint_ops;
|
||||
|
||||
/* An instance of this type is used to represent an solib catchpoint.
|
||||
It includes a "struct breakpoint" as a kind of base class; users
|
||||
downcast to "struct breakpoint *" when needed. A breakpoint is
|
||||
really of this type iff its ops pointer points to
|
||||
A breakpoint is really of this type iff its ops pointer points to
|
||||
CATCH_SOLIB_BREAKPOINT_OPS. */
|
||||
|
||||
struct solib_catchpoint
|
||||
struct solib_catchpoint : public breakpoint
|
||||
{
|
||||
/* The base class. */
|
||||
struct breakpoint base;
|
||||
~solib_catchpoint () override;
|
||||
|
||||
/* True for "catch load", false for "catch unload". */
|
||||
unsigned char is_load;
|
||||
@ -8298,16 +8285,11 @@ struct solib_catchpoint
|
||||
regex_t compiled;
|
||||
};
|
||||
|
||||
static void
|
||||
dtor_catch_solib (struct breakpoint *b)
|
||||
solib_catchpoint::~solib_catchpoint ()
|
||||
{
|
||||
struct solib_catchpoint *self = (struct solib_catchpoint *) b;
|
||||
|
||||
if (self->regex)
|
||||
regfree (&self->compiled);
|
||||
xfree (self->regex);
|
||||
|
||||
base_breakpoint_ops.dtor (b);
|
||||
if (this->regex)
|
||||
regfree (&this->compiled);
|
||||
xfree (this->regex);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -8344,7 +8326,7 @@ breakpoint_hit_catch_solib (const struct bp_location *bl,
|
||||
if (other->type != bp_shlib_event)
|
||||
continue;
|
||||
|
||||
if (self->base.pspace != NULL && other->pspace != self->base.pspace)
|
||||
if (self->pspace != NULL && other->pspace != self->pspace)
|
||||
continue;
|
||||
|
||||
for (other_bl = other->loc; other_bl != NULL; other_bl = other_bl->next)
|
||||
@ -8518,13 +8500,13 @@ add_solib_catchpoint (const char *arg, int is_load, int is_temp, int enabled)
|
||||
}
|
||||
|
||||
c->is_load = is_load;
|
||||
init_catchpoint (&c->base, gdbarch, is_temp, NULL,
|
||||
init_catchpoint (c, gdbarch, is_temp, NULL,
|
||||
&catch_solib_breakpoint_ops);
|
||||
|
||||
c->base.enable_state = enabled ? bp_enabled : bp_disabled;
|
||||
c->enable_state = enabled ? bp_enabled : bp_disabled;
|
||||
|
||||
discard_cleanups (cleanup);
|
||||
install_breakpoint (0, &c->base, 1);
|
||||
install_breakpoint (0, c, 1);
|
||||
}
|
||||
|
||||
/* A helper function that does all the work for "catch load" and
|
||||
@ -8600,25 +8582,22 @@ create_fork_vfork_event_catchpoint (struct gdbarch *gdbarch,
|
||||
{
|
||||
struct fork_catchpoint *c = new fork_catchpoint ();
|
||||
|
||||
init_catchpoint (&c->base, gdbarch, tempflag, cond_string, ops);
|
||||
init_catchpoint (c, gdbarch, tempflag, cond_string, ops);
|
||||
|
||||
c->forked_inferior_pid = null_ptid;
|
||||
|
||||
install_breakpoint (0, &c->base, 1);
|
||||
install_breakpoint (0, c, 1);
|
||||
}
|
||||
|
||||
/* Exec catchpoints. */
|
||||
|
||||
/* An instance of this type is used to represent an exec catchpoint.
|
||||
It includes a "struct breakpoint" as a kind of base class; users
|
||||
downcast to "struct breakpoint *" when needed. A breakpoint is
|
||||
really of this type iff its ops pointer points to
|
||||
A breakpoint is really of this type iff its ops pointer points to
|
||||
CATCH_EXEC_BREAKPOINT_OPS. */
|
||||
|
||||
struct exec_catchpoint
|
||||
struct exec_catchpoint : public breakpoint
|
||||
{
|
||||
/* The base class. */
|
||||
struct breakpoint base;
|
||||
~exec_catchpoint () override;
|
||||
|
||||
/* Filename of a program whose exec triggered this catchpoint.
|
||||
This field is only valid immediately after this catchpoint has
|
||||
@ -8626,17 +8605,11 @@ struct exec_catchpoint
|
||||
char *exec_pathname;
|
||||
};
|
||||
|
||||
/* Implement the "dtor" breakpoint_ops method for exec
|
||||
catchpoints. */
|
||||
/* Exec catchpoint destructor. */
|
||||
|
||||
static void
|
||||
dtor_catch_exec (struct breakpoint *b)
|
||||
exec_catchpoint::~exec_catchpoint ()
|
||||
{
|
||||
struct exec_catchpoint *c = (struct exec_catchpoint *) b;
|
||||
|
||||
xfree (c->exec_pathname);
|
||||
|
||||
base_breakpoint_ops.dtor (b);
|
||||
xfree (this->exec_pathname);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -10510,18 +10483,13 @@ watchpoint_exp_is_const (const struct expression *exp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Implement the "dtor" breakpoint_ops method for watchpoints. */
|
||||
/* Watchpoint destructor. */
|
||||
|
||||
static void
|
||||
dtor_watchpoint (struct breakpoint *self)
|
||||
watchpoint::~watchpoint ()
|
||||
{
|
||||
struct watchpoint *w = (struct watchpoint *) self;
|
||||
|
||||
xfree (w->exp_string);
|
||||
xfree (w->exp_string_reparse);
|
||||
value_free (w->val);
|
||||
|
||||
base_breakpoint_ops.dtor (self);
|
||||
xfree (this->exp_string);
|
||||
xfree (this->exp_string_reparse);
|
||||
value_free (this->val);
|
||||
}
|
||||
|
||||
/* Implement the "re_set" breakpoint_ops method for watchpoints. */
|
||||
@ -11006,7 +10974,7 @@ static void
|
||||
watch_command_1 (const char *arg, int accessflag, int from_tty,
|
||||
int just_location, int internal)
|
||||
{
|
||||
struct breakpoint *b, *scope_breakpoint = NULL;
|
||||
struct breakpoint *scope_breakpoint = NULL;
|
||||
const struct block *exp_valid_block = NULL, *cond_exp_valid_block = NULL;
|
||||
struct value *val, *mark, *result;
|
||||
int saved_bitpos = 0, saved_bitsize = 0;
|
||||
@ -11245,16 +11213,16 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
|
||||
bp_type = bp_hardware_watchpoint;
|
||||
|
||||
w = new watchpoint ();
|
||||
b = &w->base;
|
||||
|
||||
if (use_mask)
|
||||
init_raw_breakpoint_without_location (b, NULL, bp_type,
|
||||
init_raw_breakpoint_without_location (w, NULL, bp_type,
|
||||
&masked_watchpoint_breakpoint_ops);
|
||||
else
|
||||
init_raw_breakpoint_without_location (b, NULL, bp_type,
|
||||
init_raw_breakpoint_without_location (w, NULL, bp_type,
|
||||
&watchpoint_breakpoint_ops);
|
||||
b->thread = thread;
|
||||
b->disposition = disp_donttouch;
|
||||
b->pspace = current_program_space;
|
||||
w->thread = thread;
|
||||
w->disposition = disp_donttouch;
|
||||
w->pspace = current_program_space;
|
||||
w->exp = std::move (exp);
|
||||
w->exp_valid_block = exp_valid_block;
|
||||
w->cond_exp_valid_block = cond_exp_valid_block;
|
||||
@ -11285,9 +11253,9 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
|
||||
}
|
||||
|
||||
if (cond_start)
|
||||
b->cond_string = savestring (cond_start, cond_end - cond_start);
|
||||
w->cond_string = savestring (cond_start, cond_end - cond_start);
|
||||
else
|
||||
b->cond_string = 0;
|
||||
w->cond_string = 0;
|
||||
|
||||
if (frame_id_p (watchpoint_frame))
|
||||
{
|
||||
@ -11304,8 +11272,8 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
|
||||
{
|
||||
/* The scope breakpoint is related to the watchpoint. We will
|
||||
need to act on them together. */
|
||||
b->related_breakpoint = scope_breakpoint;
|
||||
scope_breakpoint->related_breakpoint = b;
|
||||
w->related_breakpoint = scope_breakpoint;
|
||||
scope_breakpoint->related_breakpoint = w;
|
||||
}
|
||||
|
||||
if (!just_location)
|
||||
@ -11319,12 +11287,12 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
|
||||
}
|
||||
CATCH (e, RETURN_MASK_ALL)
|
||||
{
|
||||
delete_breakpoint (b);
|
||||
delete_breakpoint (w);
|
||||
throw_exception (e);
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
install_breakpoint (internal, b, 1);
|
||||
install_breakpoint (internal, w, 1);
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
||||
@ -11794,11 +11762,11 @@ catch_exec_command_1 (char *arg_entry, int from_tty,
|
||||
error (_("Junk at end of arguments."));
|
||||
|
||||
c = new exec_catchpoint ();
|
||||
init_catchpoint (&c->base, gdbarch, tempflag, cond_string,
|
||||
init_catchpoint (c, gdbarch, tempflag, cond_string,
|
||||
&catch_exec_breakpoint_ops);
|
||||
c->exec_pathname = NULL;
|
||||
|
||||
install_breakpoint (0, &c->base, 1);
|
||||
install_breakpoint (0, c, 1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -12763,16 +12731,14 @@ static const struct bp_location_ops bp_location_ops =
|
||||
bp_location_dtor
|
||||
};
|
||||
|
||||
/* Default breakpoint_ops methods all breakpoint_ops ultimately
|
||||
inherit from. */
|
||||
/* Destructor for the breakpoint base class. */
|
||||
|
||||
static void
|
||||
base_breakpoint_dtor (struct breakpoint *self)
|
||||
breakpoint::~breakpoint ()
|
||||
{
|
||||
decref_counted_command_line (&self->commands);
|
||||
xfree (self->cond_string);
|
||||
xfree (self->extra_string);
|
||||
xfree (self->filter);
|
||||
decref_counted_command_line (&this->commands);
|
||||
xfree (this->cond_string);
|
||||
xfree (this->extra_string);
|
||||
xfree (this->filter);
|
||||
}
|
||||
|
||||
static struct bp_location *
|
||||
@ -12913,7 +12879,6 @@ base_breakpoint_after_condition_true (struct bpstats *bs)
|
||||
|
||||
struct breakpoint_ops base_breakpoint_ops =
|
||||
{
|
||||
base_breakpoint_dtor,
|
||||
base_breakpoint_allocate_location,
|
||||
base_breakpoint_re_set,
|
||||
base_breakpoint_insert_location,
|
||||
@ -13281,15 +13246,12 @@ momentary_bkpt_print_mention (struct breakpoint *b)
|
||||
It gets cleared already on the removal of the first one of such placed
|
||||
breakpoints. This is OK as they get all removed altogether. */
|
||||
|
||||
static void
|
||||
longjmp_bkpt_dtor (struct breakpoint *self)
|
||||
longjmp_breakpoint::~longjmp_breakpoint ()
|
||||
{
|
||||
struct thread_info *tp = find_thread_global_id (self->thread);
|
||||
thread_info *tp = find_thread_global_id (this->thread);
|
||||
|
||||
if (tp)
|
||||
if (tp != NULL)
|
||||
tp->initiating_frame = null_frame_id;
|
||||
|
||||
momentary_breakpoint_ops.dtor (self);
|
||||
}
|
||||
|
||||
/* Specific methods for probe breakpoints. */
|
||||
@ -13634,7 +13596,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
|
||||
location = copy_event_location (canonical->location.get ());
|
||||
|
||||
tp = new tracepoint ();
|
||||
init_breakpoint_sal (&tp->base, gdbarch, expanded,
|
||||
init_breakpoint_sal (tp, gdbarch, expanded,
|
||||
std::move (location), NULL,
|
||||
cond_string, extra_string,
|
||||
type_wanted, disposition,
|
||||
@ -13649,7 +13611,7 @@ strace_marker_create_breakpoints_sal (struct gdbarch *gdbarch,
|
||||
corresponds to this one */
|
||||
tp->static_trace_marker_id_idx = i;
|
||||
|
||||
install_breakpoint (internal, &tp->base, 0);
|
||||
install_breakpoint (internal, tp, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -13769,7 +13731,6 @@ delete_breakpoint (struct breakpoint *bpt)
|
||||
self-contained, but it's not the case now. */
|
||||
update_global_location_list (UGLL_DONT_INSERT);
|
||||
|
||||
bpt->ops->dtor (bpt);
|
||||
/* On the chance that someone will soon try again to delete this
|
||||
same bp, we mark it as deleted before freeing its storage. */
|
||||
bpt->type = bp_none;
|
||||
@ -15265,7 +15226,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
|
||||
if (utp->pass > 0)
|
||||
{
|
||||
xsnprintf (small_buf, sizeof (small_buf), "%d %d", utp->pass,
|
||||
tp->base.number);
|
||||
tp->number);
|
||||
|
||||
trace_pass_command (small_buf, 0);
|
||||
}
|
||||
@ -15283,7 +15244,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
|
||||
|
||||
cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL);
|
||||
|
||||
breakpoint_set_commands (&tp->base, std::move (cmd_list));
|
||||
breakpoint_set_commands (tp, std::move (cmd_list));
|
||||
}
|
||||
else if (!VEC_empty (char_ptr, utp->actions)
|
||||
|| !VEC_empty (char_ptr, utp->step_actions))
|
||||
@ -15292,7 +15253,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
|
||||
utp->number);
|
||||
|
||||
/* Copy any status information that might be available. */
|
||||
tp->base.hit_count = utp->hit_count;
|
||||
tp->hit_count = utp->hit_count;
|
||||
tp->traceframe_usage = utp->traceframe_usage;
|
||||
|
||||
return tp;
|
||||
@ -15378,10 +15339,10 @@ static void
|
||||
trace_pass_set_count (struct tracepoint *tp, int count, int from_tty)
|
||||
{
|
||||
tp->pass_count = count;
|
||||
observer_notify_breakpoint_modified (&tp->base);
|
||||
observer_notify_breakpoint_modified (tp);
|
||||
if (from_tty)
|
||||
printf_filtered (_("Setting tracepoint %d's passcount to %d\n"),
|
||||
tp->base.number, count);
|
||||
tp->number, count);
|
||||
}
|
||||
|
||||
/* Set passcount for tracepoint.
|
||||
@ -15887,11 +15848,6 @@ initialize_breakpoint_ops (void)
|
||||
ops->print_it = momentary_bkpt_print_it;
|
||||
ops->print_mention = momentary_bkpt_print_mention;
|
||||
|
||||
/* Momentary breakpoints for bp_longjmp and bp_exception. */
|
||||
ops = &longjmp_breakpoint_ops;
|
||||
*ops = momentary_breakpoint_ops;
|
||||
ops->dtor = longjmp_bkpt_dtor;
|
||||
|
||||
/* Probe breakpoints. */
|
||||
ops = &bkpt_probe_breakpoint_ops;
|
||||
*ops = bkpt_breakpoint_ops;
|
||||
@ -15903,7 +15859,6 @@ initialize_breakpoint_ops (void)
|
||||
/* Watchpoints. */
|
||||
ops = &watchpoint_breakpoint_ops;
|
||||
*ops = base_breakpoint_ops;
|
||||
ops->dtor = dtor_watchpoint;
|
||||
ops->re_set = re_set_watchpoint;
|
||||
ops->insert_location = insert_watchpoint;
|
||||
ops->remove_location = remove_watchpoint;
|
||||
@ -15978,7 +15933,6 @@ initialize_breakpoint_ops (void)
|
||||
/* Exec catchpoints. */
|
||||
ops = &catch_exec_breakpoint_ops;
|
||||
*ops = base_breakpoint_ops;
|
||||
ops->dtor = dtor_catch_exec;
|
||||
ops->insert_location = insert_catch_exec;
|
||||
ops->remove_location = remove_catch_exec;
|
||||
ops->breakpoint_hit = breakpoint_hit_catch_exec;
|
||||
@ -15990,7 +15944,6 @@ initialize_breakpoint_ops (void)
|
||||
/* Solib-related catchpoints. */
|
||||
ops = &catch_solib_breakpoint_ops;
|
||||
*ops = base_breakpoint_ops;
|
||||
ops->dtor = dtor_catch_solib;
|
||||
ops->insert_location = insert_catch_solib;
|
||||
ops->remove_location = remove_catch_solib;
|
||||
ops->breakpoint_hit = breakpoint_hit_catch_solib;
|
||||
|
@ -512,10 +512,6 @@ enum print_stop_action
|
||||
|
||||
struct breakpoint_ops
|
||||
{
|
||||
/* Destructor. Releases everything from SELF (but not SELF
|
||||
itself). */
|
||||
void (*dtor) (struct breakpoint *self);
|
||||
|
||||
/* Allocate a location for this breakpoint. */
|
||||
struct bp_location * (*allocate_location) (struct breakpoint *);
|
||||
|
||||
@ -680,6 +676,8 @@ extern int target_exact_watchpoints;
|
||||
|
||||
struct breakpoint
|
||||
{
|
||||
virtual ~breakpoint ();
|
||||
|
||||
/* Methods associated with this breakpoint. */
|
||||
const breakpoint_ops *ops = NULL;
|
||||
|
||||
@ -783,14 +781,11 @@ struct breakpoint
|
||||
gdbscm_breakpoint_object *scm_bp_object = NULL;
|
||||
};
|
||||
|
||||
/* An instance of this type is used to represent a watchpoint. It
|
||||
includes a "struct breakpoint" as a kind of base class; users
|
||||
downcast to "struct breakpoint *" when needed. */
|
||||
/* An instance of this type is used to represent a watchpoint. */
|
||||
|
||||
struct watchpoint
|
||||
struct watchpoint : public breakpoint
|
||||
{
|
||||
/* The base class. */
|
||||
struct breakpoint base;
|
||||
~watchpoint () override;
|
||||
|
||||
/* String form of exp to use for displaying to the user (malloc'd),
|
||||
or NULL if none. */
|
||||
@ -867,14 +862,10 @@ extern int is_breakpoint (const struct breakpoint *bpt);
|
||||
extern int is_watchpoint (const struct breakpoint *bpt);
|
||||
|
||||
/* An instance of this type is used to represent all kinds of
|
||||
tracepoints. It includes a "struct breakpoint" as a kind of base
|
||||
class; users downcast to "struct breakpoint *" when needed. */
|
||||
tracepoints. */
|
||||
|
||||
struct tracepoint
|
||||
struct tracepoint : public breakpoint
|
||||
{
|
||||
/* The base class. */
|
||||
struct breakpoint base;
|
||||
|
||||
/* Number of times this tracepoint should single-step and collect
|
||||
additional data. */
|
||||
long step_count;
|
||||
|
@ -1522,8 +1522,8 @@ ctf_get_traceframe_address (void)
|
||||
struct tracepoint *tp
|
||||
= get_tracepoint_by_number_on_target (tpnum);
|
||||
|
||||
if (tp && tp->base.loc)
|
||||
addr = tp->base.loc->address;
|
||||
if (tp && tp->loc)
|
||||
addr = tp->loc->address;
|
||||
}
|
||||
|
||||
/* Restore the position. */
|
||||
|
@ -398,7 +398,7 @@ mi_cmd_break_passcount (const char *command, char **argv, int argc)
|
||||
if (t)
|
||||
{
|
||||
t->pass_count = p;
|
||||
observer_notify_breakpoint_modified (&t->base);
|
||||
observer_notify_breakpoint_modified (t);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -12650,9 +12650,9 @@ remote_get_tracepoint_status (struct target_ops *self, struct breakpoint *bp,
|
||||
|
||||
if (tp)
|
||||
{
|
||||
tp->base.hit_count = 0;
|
||||
tp->hit_count = 0;
|
||||
tp->traceframe_usage = 0;
|
||||
for (loc = tp->base.loc; loc; loc = loc->next)
|
||||
for (loc = tp->loc; loc; loc = loc->next)
|
||||
{
|
||||
/* If the tracepoint was never downloaded, don't go asking for
|
||||
any status. */
|
||||
|
@ -650,8 +650,8 @@ tfile_get_traceframe_address (off_t tframe_offset)
|
||||
|
||||
tp = get_tracepoint_by_number_on_target (tpnum);
|
||||
/* FIXME this is a poor heuristic if multiple locations. */
|
||||
if (tp && tp->base.loc)
|
||||
addr = tp->base.loc->address;
|
||||
if (tp && tp->loc)
|
||||
addr = tp->loc->address;
|
||||
|
||||
/* Restore our seek position. */
|
||||
cur_offset = saved_offset;
|
||||
|
@ -398,15 +398,15 @@ tracefile_fetch_registers (struct regcache *regcache, int regno)
|
||||
|
||||
/* We can often usefully guess that the PC is going to be the same
|
||||
as the address of the tracepoint. */
|
||||
if (tp == NULL || tp->base.loc == NULL)
|
||||
if (tp == NULL || tp->loc == NULL)
|
||||
return;
|
||||
|
||||
/* But don't try to guess if tracepoint is multi-location... */
|
||||
if (tp->base.loc->next)
|
||||
if (tp->loc->next)
|
||||
{
|
||||
warning (_("Tracepoint %d has multiple "
|
||||
"locations, cannot infer $pc"),
|
||||
tp->base.number);
|
||||
tp->number);
|
||||
return;
|
||||
}
|
||||
/* ... or does while-stepping. */
|
||||
@ -414,13 +414,13 @@ tracefile_fetch_registers (struct regcache *regcache, int regno)
|
||||
{
|
||||
warning (_("Tracepoint %d does while-stepping, "
|
||||
"cannot infer $pc"),
|
||||
tp->base.number);
|
||||
tp->number);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Guess what we can from the tracepoint location. */
|
||||
gdbarch_guess_tracepoint_registers (gdbarch, regcache,
|
||||
tp->base.loc->address);
|
||||
tp->loc->address);
|
||||
}
|
||||
|
||||
/* This is the implementation of target_ops method to_has_all_memory. */
|
||||
|
@ -648,11 +648,11 @@ actions_command (char *args, int from_tty)
|
||||
{
|
||||
std::string tmpbuf =
|
||||
string_printf ("Enter actions for tracepoint %d, one per line.",
|
||||
t->base.number);
|
||||
t->number);
|
||||
|
||||
command_line_up l = read_command_lines (&tmpbuf[0], from_tty, 1,
|
||||
check_tracepoint_command, t);
|
||||
breakpoint_set_commands (&t->base, std::move (l));
|
||||
breakpoint_set_commands (t, std::move (l));
|
||||
}
|
||||
/* else just return */
|
||||
}
|
||||
@ -738,7 +738,7 @@ validate_actionline (const char *line, struct breakpoint *b)
|
||||
/* else fall thru, treat p as an expression and parse it! */
|
||||
}
|
||||
tmp_p = p;
|
||||
for (loc = t->base.loc; loc; loc = loc->next)
|
||||
for (loc = t->loc; loc; loc = loc->next)
|
||||
{
|
||||
p = tmp_p;
|
||||
expression_up exp = parse_exp_1 (&p, loc->address,
|
||||
@ -788,7 +788,7 @@ validate_actionline (const char *line, struct breakpoint *b)
|
||||
p = skip_spaces_const (p);
|
||||
|
||||
tmp_p = p;
|
||||
for (loc = t->base.loc; loc; loc = loc->next)
|
||||
for (loc = t->loc; loc; loc = loc->next)
|
||||
{
|
||||
p = tmp_p;
|
||||
|
||||
@ -2246,7 +2246,7 @@ tfind_1 (enum trace_find_type type, int num,
|
||||
reinit_frame_cache ();
|
||||
target_dcache_invalidate ();
|
||||
|
||||
set_tracepoint_num (tp ? tp->base.number : target_tracept);
|
||||
set_tracepoint_num (tp ? tp->number : target_tracept);
|
||||
|
||||
if (target_frameno != get_traceframe_number ())
|
||||
observer_notify_traceframe_changed (target_frameno, tracepoint_number);
|
||||
@ -2870,7 +2870,7 @@ get_traceframe_location (int *stepping_frame_p)
|
||||
locations, assume it is a direct hit rather than a while-stepping
|
||||
frame. (FIXME this is not reliable, should record each frame's
|
||||
type.) */
|
||||
for (tloc = t->base.loc; tloc; tloc = tloc->next)
|
||||
for (tloc = t->loc; tloc; tloc = tloc->next)
|
||||
if (tloc->address == regcache_read_pc (regcache))
|
||||
{
|
||||
*stepping_frame_p = 0;
|
||||
@ -2880,7 +2880,7 @@ get_traceframe_location (int *stepping_frame_p)
|
||||
/* If this is a stepping frame, we don't know which location
|
||||
triggered. The first is as good (or bad) a guess as any... */
|
||||
*stepping_frame_p = 1;
|
||||
return t->base.loc;
|
||||
return t->loc;
|
||||
}
|
||||
|
||||
/* Return all the actions, including default collect, of a tracepoint
|
||||
@ -3231,7 +3231,7 @@ find_matching_tracepoint_location (struct uploaded_tp *utp)
|
||||
if (b->type == utp->type
|
||||
&& t->step_count == utp->step
|
||||
&& t->pass_count == utp->pass
|
||||
&& cond_string_is_same (t->base.cond_string, utp->cond_string)
|
||||
&& cond_string_is_same (t->cond_string, utp->cond_string)
|
||||
/* FIXME also test actions. */
|
||||
)
|
||||
{
|
||||
@ -3300,7 +3300,7 @@ merge_uploaded_tracepoints (struct uploaded_tp **uploaded_tps)
|
||||
if (t)
|
||||
printf_filtered (_("Created tracepoint %d for "
|
||||
"target's tracepoint %d at %s.\n"),
|
||||
t->base.number, utp->number,
|
||||
t->number, utp->number,
|
||||
paddress (get_current_arch (), utp->addr));
|
||||
else
|
||||
printf_filtered (_("Failed to create tracepoint for target's "
|
||||
@ -3603,7 +3603,7 @@ parse_tracepoint_status (char *p, struct breakpoint *bp,
|
||||
|
||||
p = unpack_varlen_hex (p, &uval);
|
||||
if (tp)
|
||||
tp->base.hit_count += uval;
|
||||
tp->hit_count += uval;
|
||||
else
|
||||
utp->hit_count += uval;
|
||||
p = unpack_varlen_hex (p + 1, &uval);
|
||||
|
Loading…
x
Reference in New Issue
Block a user