more OO, use breakpoints_ops for all kinds of breakpoints (Re: [patch] [python] Expose some breakpoint operations to Python)

Pedro Alves
2011-06-24T16:42:04Z

On Thursday 23 June 2011 18:04:26, Pedro Alves wrote:

> I'd like to finish that conversion soon.

I did a bit more work on this. Watchpoints were already using
breakpoint_ops. I added a bkpt_breakpoint_ops for all software/hardware
breakpoints, and a tracepoint_ops for all kinds of tracepoints,
and moved the default actions to the appropriate places. There
were places where I could cleanup a bit further, but I figured
I'd better do those as follow ups. I think these 4 major
kinds of "breakpoints" is already a good start. Further
refinement could split internal / momentary breakpoints
into its own ops, for example.

I left behind the print_one method, as that seems will
require something else, or some disentanglement.

The current insert/remove abstration is at raw location level.
We can't use it as is to split insert_bp_location. We may need
to rename the current methods to e.g., insert_raw_location (or
move them to the bp_location vtable), and add new breakpoint_ops
methods that call the raw methods, and, handle the different
warnings and insert-failed->revert paths as appropriate per
breakpoint type.

This has no regressions for me. It misses some comments and
cosmetics here and there, and a ChangeLog entry. I'll try to
get back to this soon, but I've got other fish to fry at
the moment.

--
Pedro Alves

---
gdb/ada-lang.c | 56 -
gdb/breakpoint.c | 2076 ++++++++++++++++++++++++---------------------
gdb/breakpoint.h | 48 -
gdb/mi/mi-cmd-break.c | 2
gdb/python/py-breakpoint.c | 3
5 files changed, 1203 insertions(+), 982 deletions(-)

Index: src/gdb/breakpoint.c
===================================================================
--- src.orig/gdb/breakpoint.c 2011-06-23 01:25:32.000000000 +0100
+++ src/gdb/breakpoint.c 2011-06-24 17:29:05.868082452 +0100
@@ -94,6 +94,8 @@ static void ignore_command (char *, int)

static int breakpoint_re_set_one (void *);

+static void breakpoint_re_set_default (struct breakpoint *);
+
static void clear_command (char *, int);

static void catch_command (char *, int);
@@ -104,11 +106,14 @@ static void break_command_1 (char *, int

static void mention (struct breakpoint *);

+static struct breakpoint *set_raw_breakpoint_without_location (struct gdbarch *,
+ enum bptype,
+ struct breakpoint_ops *);
/* This function is used in gdbtk sources and thus can not be made
static. */
struct breakpoint *set_raw_breakpoint (struct gdbarch *gdbarch,
- struct symtab_and_line,
- enum bptype);
+ struct symtab_and_line,
+ enum bptype, struct breakpoint_ops *);

static void breakpoint_adjustment_warning (CORE_ADDR, CORE_ADDR, int, int);

@@ -157,8 +162,6 @@ insertion_state_t;
static int remove_breakpoint (struct bp_location *, insertion_state_t);
static int remove_breakpoint_1 (struct bp_location *, insertion_state_t);

-static enum print_stop_action print_it_typical (bpstat);
-
static enum print_stop_action print_bp_stop_message (bpstat bs);

static int watchpoint_check (void *);
@@ -1436,10 +1439,7 @@ update_watchpoint (struct breakpoint *b,
(b->type, i, other_type_used);
if (target_resources_ok <= 0)
{
- /* If there's no works_in_software_mode method, we
- assume that the watchpoint works in software mode. */
- int sw_mode = (!b->ops || !b->ops->works_in_software_mode
- || b->ops->works_in_software_mode (b));
+ 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 "
@@ -1451,8 +1451,7 @@ update_watchpoint (struct breakpoint *b,
b->type = bp_watchpoint;
}
}
- else if (b->ops && b->ops->works_in_software_mode
- && !b->ops->works_in_software_mode (b))
+ else if (!b->ops->works_in_software_mode (b))
error (_("Expression cannot be implemented with "
"read/access watchpoint."));
else
@@ -1622,12 +1621,7 @@ insert_bp_location (struct bp_location *
{
/* No overlay handling: just set the breakpoint. */

- if (bl->loc_type == bp_loc_hardware_breakpoint)
- val = target_insert_hw_breakpoint (bl->gdbarch,
- &bl->target_info);
- else
- val = target_insert_breakpoint (bl->gdbarch,
- &bl->target_info);
+ val = bl->owner->ops->insert_location (bl);
}
else
{
@@ -1661,12 +1655,7 @@ insert_bp_location (struct bp_location *
if (section_is_mapped (bl->section))
{
/* Yes. This overlay section is mapped into memory. */
- if (bl->loc_type == bp_loc_hardware_breakpoint)
- val = target_insert_hw_breakpoint (bl->gdbarch,
- &bl->target_info);
- else
- val = target_insert_breakpoint (bl->gdbarch,
- &bl->target_info);
+ val = bl->owner->ops->insert_location (bl);
}
else
{
@@ -2088,7 +2077,7 @@ create_internal_breakpoint (struct gdbar
sal.section = find_pc_overlay (sal.pc);
sal.pspace = current_program_space;

- b = set_raw_breakpoint (gdbarch, sal, type);
+ b = set_raw_breakpoint (gdbarch, sal, type, &bkpt_breakpoint_ops);
b->number = internal_breakpoint_number--;
b->disposition = disp_donttouch;

@@ -2547,11 +2536,7 @@ remove_breakpoint_1 (struct bp_location
|| !(section_is_overlay (bl->section)))
{
/* No overlay handling: just remove the breakpoint. */
-
- if (bl->loc_type == bp_loc_hardware_breakpoint)
- val = target_remove_hw_breakpoint (bl->gdbarch, &bl->target_info);
- else
- val = target_remove_breakpoint (bl->gdbarch, &bl->target_info);
+ val = bl->owner->ops->remove_location (bl);
}
else
{
@@ -2579,16 +2564,13 @@ remove_breakpoint_1 (struct bp_location
remove the breakpoint if the section had been
unmapped, but let's not rely on that being safe. We
don't know what the overlay manager might do. */
- if (bl->loc_type == bp_loc_hardware_breakpoint)
- val = target_remove_hw_breakpoint (bl->gdbarch,
- &bl->target_info);

/* However, we should remove *software* breakpoints only
if the section is still mapped, or else we overwrite
wrong code with the saved shadow contents. */
- else if (section_is_mapped (bl->section))
- val = target_remove_breakpoint (bl->gdbarch,
- &bl->target_info);
+ if (bl->loc_type == bp_loc_hardware_breakpoint
+ || section_is_mapped (bl->section))
+ val = bl->owner->ops->remove_location (bl);
else
val = 0;
}
@@ -3305,219 +3287,6 @@ watchpoint_value_print (struct value *va
}
}

-/* This is the normal print function for a bpstat. In the future,
- much of this logic could (should?) be moved to bpstat_stop_status,
- by having it set different print_it values.
-
- Current scheme: When we stop, bpstat_print() is called. It loops
- through the bpstat list of things causing this stop, calling the
- print_bp_stop_message function on each one. The behavior of the
- print_bp_stop_message function depends on the print_it field of
- bpstat. If such field so indicates, call this function here.
-
- Return values from this routine (ultimately used by bpstat_print()
- and normal_stop() to decide what to do):
- PRINT_NOTHING: Means we already printed all we needed to print,
- don't print anything else.
- PRINT_SRC_ONLY: Means we printed something, and we do *not* desire
- that something to be followed by a location.
- PRINT_SCR_AND_LOC: Means we printed something, and we *do* desire
- that something to be followed by a location.
- PRINT_UNKNOWN: Means we printed nothing or we need to do some more
- analysis. */
-
-static enum print_stop_action
-print_it_typical (bpstat bs)
-{
- struct cleanup *old_chain;
- struct breakpoint *b;
- const struct bp_location *bl;
- struct ui_stream *stb;
- int bp_temp = 0;
- enum print_stop_action result;
-
- gdb_assert (bs->bp_location_at != NULL);
-
- bl = bs->bp_location_at;
- b = bs->breakpoint_at;
-
- stb = ui_out_stream_new (uiout);
- old_chain = make_cleanup_ui_out_stream_delete (stb);
-
- switch (b->type)
- {
- case bp_breakpoint:
- case bp_hardware_breakpoint:
- bp_temp = b->disposition == disp_del;
- if (bl->address != bl->requested_address)
- breakpoint_adjustment_warning (bl->requested_address,
- bl->address,
- b->number, 1);
- annotate_breakpoint (b->number);
- if (bp_temp)
- ui_out_text (uiout, "\nTemporary breakpoint ");
- else
- ui_out_text (uiout, "\nBreakpoint ");
- if (ui_out_is_mi_like_p (uiout))
- {
- ui_out_field_string (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
- ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
- }
- ui_out_field_int (uiout, "bkptno", b->number);
- ui_out_text (uiout, ", ");
- result = PRINT_SRC_AND_LOC;
- break;
-
- case bp_shlib_event:
- /* Did we stop because the user set the stop_on_solib_events
- variable? (If so, we report this as a generic, "Stopped due
- to shlib event" message.) */
- printf_filtered (_("Stopped due to shared library event\n"));
- result = PRINT_NOTHING;
- break;
-
- case bp_thread_event:
- /* Not sure how we will get here.
- GDB should not stop for these breakpoints. */
- printf_filtered (_("Thread Event Breakpoint: gdb should not stop!\n"));
- result = PRINT_NOTHING;
- break;
-
- case bp_overlay_event:
- /* By analogy with the thread event, GDB should not stop for these. */
- printf_filtered (_("Overlay Event Breakpoint: gdb should not stop!\n"));
- result = PRINT_NOTHING;
- break;
-
- case bp_longjmp_master:
- /* These should never be enabled. */
- printf_filtered (_("Longjmp Master Breakpoint: gdb should not stop!\n"));
- result = PRINT_NOTHING;
- break;
-
- case bp_std_terminate_master:
- /* These should never be enabled. */
- printf_filtered (_("std::terminate Master Breakpoint: "
- "gdb should not stop!\n"));
- result = PRINT_NOTHING;
- break;
-
- case bp_exception_master:
- /* These should never be enabled. */
- printf_filtered (_("Exception Master Breakpoint: "
- "gdb should not stop!\n"));
- result = PRINT_NOTHING;
- break;
-
- case bp_watchpoint:
- case bp_hardware_watchpoint:
- annotate_watchpoint (b->number);
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
- mention (b);
- make_cleanup_ui_out_tuple_begin_end (uiout, "value");
- ui_out_text (uiout, "\nOld value = ");
- watchpoint_value_print (bs->old_val, stb->stream);
- ui_out_field_stream (uiout, "old", stb);
- ui_out_text (uiout, "\nNew value = ");
- watchpoint_value_print (b->val, stb->stream);
- ui_out_field_stream (uiout, "new", stb);
- ui_out_text (uiout, "\n");
- /* More than one watchpoint may have been triggered. */
- result = PRINT_UNKNOWN;
- break;
-
- case bp_read_watchpoint:
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
- mention (b);
- make_cleanup_ui_out_tuple_begin_end (uiout, "value");
- ui_out_text (uiout, "\nValue = ");
- watchpoint_value_print (b->val, stb->stream);
- ui_out_field_stream (uiout, "value", stb);
- ui_out_text (uiout, "\n");
- result = PRINT_UNKNOWN;
- break;
-
- case bp_access_watchpoint:
- if (bs->old_val != NULL)
- {
- annotate_watchpoint (b->number);
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
- mention (b);
- make_cleanup_ui_out_tuple_begin_end (uiout, "value");
- ui_out_text (uiout, "\nOld value = ");
- watchpoint_value_print (bs->old_val, stb->stream);
- ui_out_field_stream (uiout, "old", stb);
- ui_out_text (uiout, "\nNew value = ");
- }
- else
- {
- mention (b);
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
- make_cleanup_ui_out_tuple_begin_end (uiout, "value");
- ui_out_text (uiout, "\nValue = ");
- }
- watchpoint_value_print (b->val, stb->stream);
- ui_out_field_stream (uiout, "new", stb);
- ui_out_text (uiout, "\n");
- result = PRINT_UNKNOWN;
- break;
-
- /* Fall through, we don't deal with these types of breakpoints
- here. */
-
- case bp_finish:
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_FUNCTION_FINISHED));
- result = PRINT_UNKNOWN;
- break;
-
- case bp_until:
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_LOCATION_REACHED));
- result = PRINT_UNKNOWN;
- break;
-
- case bp_none:
- case bp_longjmp:
- case bp_longjmp_resume:
- case bp_exception:
- case bp_exception_resume:
- case bp_step_resume:
- case bp_hp_step_resume:
- case bp_watchpoint_scope:
- case bp_call_dummy:
- case bp_std_terminate:
- case bp_tracepoint:
- case bp_fast_tracepoint:
- case bp_jit_event:
- case bp_gnu_ifunc_resolver:
- case bp_gnu_ifunc_resolver_return:
- default:
- result = PRINT_UNKNOWN;
- break;
- }
-
- do_cleanups (old_chain);
- return result;
-}
-
/* Generic routine for printing messages indicating why we
stopped. The behavior of this function depends on the value
'print_it' in the bpstat structure. Under some circumstances we
@@ -3549,14 +3318,10 @@ print_bp_stop_message (bpstat bs)
if (b == NULL)
return PRINT_UNKNOWN;

- /* Normal case. Call the breakpoint's print_it method, or
- print_it_typical. */
- if (b->ops != NULL && b->ops->print_it != NULL)
- return b->ops->print_it (b);
- else
- return print_it_typical (bs);
+ /* Normal case. Call the breakpoint's print_it method. */
+ return b->ops->print_it (bs);
}
- break;
+ break;

default:
internal_error (__FILE__, __LINE__,
@@ -3851,10 +3616,11 @@ watchpoint_check (void *p)
So we can't even detect the first assignment to it and
watch after that (since the garbage may or may not equal
the first value assigned). */
- /* We print all the stop information in print_it_typical(), but
- in this case, by the time we call print_it_typical() this bp
- will be deleted already. So we have no choice but print the
- information here. */
+ /* We print all the stop information in
+ breakpoint_ops->print_it, but in this case, by the time we
+ call breakpoint_ops->print_it this bp will be deleted
+ already. So we have no choice but print the information
+ here. */
if (ui_out_is_mi_like_p (uiout))
ui_out_field_string
(uiout, "reason", async_reason_lookup (EXEC_ASYNC_WATCHPOINT_SCOPE));
@@ -3873,60 +3639,19 @@ which its expression is valid.\n");
}

/* Return true if it looks like target has stopped due to hitting
- breakpoint location BL. This function does not check if we
- should stop, only if BL explains the stop. */
+ breakpoint location BL. This function does not check if we should
+ stop, only if BL explains the stop. */
+
static int
bpstat_check_location (const struct bp_location *bl,
struct address_space *aspace, CORE_ADDR bp_addr)
{
struct breakpoint *b = bl->owner;

- /* BL is from existing struct breakpoint. */
+ /* BL is from an existing breakpoint. */
gdb_assert (b != NULL);

- if (b->ops && b->ops->breakpoint_hit)
- return b->ops->breakpoint_hit (bl, aspace, bp_addr);
-
- /* By definition, the inferior does not report stops at
- tracepoints. */
- if (is_tracepoint (b))
- return 0;
-
- if (!is_watchpoint (b)
- && b->type != bp_hardware_breakpoint
- && b->type != bp_catchpoint) /* a non-watchpoint bp */
- {
- if (!breakpoint_address_match (bl->pspace->aspace, bl->address,
- aspace, bp_addr))
- return 0;
- if (overlay_debugging /* unmapped overlay section */
- && section_is_overlay (bl->section)
- && !section_is_mapped (bl->section))
- return 0;
- }
-
- /* Continuable hardware watchpoints are treated as non-existent if the
- reason we stopped wasn't a hardware watchpoint (we didn't stop on
- some data address). Otherwise gdb won't stop on a break instruction
- in the code (not from a breakpoint) when a hardware watchpoint has
- been defined. Also skip watchpoints which we know did not trigger
- (did not match the data address). */
-
- if (is_hardware_watchpoint (b)
- && b->watchpoint_triggered == watch_triggered_no)
- return 0;
-
- if (b->type == bp_hardware_breakpoint)
- {
- if (bl->address != bp_addr)
- return 0;
- if (overlay_debugging /* unmapped overlay section */
- && section_is_overlay (bl->section)
- && !section_is_mapped (bl->section))
- return 0;
- }
-
- return 1;
+ return b->ops->breakpoint_hit (bl, aspace, bp_addr);
}

/* If BS refers to a watchpoint, determine if the watched values
@@ -4307,27 +4032,11 @@ bpstat_stop_status (struct address_space
if (!bs->stop)
continue;

- bpstat_check_watchpoint (bs);
- if (!bs->stop)
- continue;
-
b = bs->breakpoint_at;
-
- if (b->ops != NULL && b->ops->check_status != NULL)
+ b->ops->check_status (bs);
+ if (bs->stop)
{
- b->ops->check_status (bs);
- if (!bs->stop)
- continue;
- }
-
- if (b->type == bp_thread_event || b->type == bp_overlay_event
- || b->type == bp_longjmp_master
- || b->type == bp_std_terminate_master
- || b->type == bp_exception_master)
- /* We do not stop for these. */
- bs->stop = 0;
- else
- bpstat_check_breakpoint_conditions (bs, ptid);
+ bpstat_check_breakpoint_conditions (bs, ptid);

if (bs->stop)
{
@@ -4360,6 +4069,7 @@ bpstat_stop_status (struct address_space
/* Print nothing for this entry if we dont stop or dont print. */
if (bs->stop == 0 || bs->print == 0)
bs->print_it = print_it_noop;
+ }
}

/* If we aren't stopping, the value of some hardware watchpoint may
@@ -4992,19 +4702,9 @@ print_one_breakpoint_location (struct br

ui_out_text (uiout, "\n");

- if (!part_of_multiple && b->ops && b->ops->print_one_detail)
+ if (!part_of_multiple)
b->ops->print_one_detail (b, uiout);

- if (!part_of_multiple && b->static_trace_marker_id)
- {
- gdb_assert (b->type == bp_static_tracepoint);
-
- ui_out_text (uiout, "\tmarker id is ");
- ui_out_field_string (uiout, "static-tracepoint-marker-string-id",
- b->static_trace_marker_id);
- ui_out_text (uiout, "\n");
- }
-
if (part_of_multiple && frame_id_p (b->frame_id))
{
annotate_field (6);
@@ -5695,6 +5395,8 @@ init_bp_location (struct bp_location *lo
{
memset (loc, 0, sizeof (*loc));

+ gdb_assert (ops != NULL);
+
loc->ops = ops;
loc->owner = owner;
loc->cond = NULL;
@@ -5753,28 +5455,13 @@ init_bp_location (struct bp_location *lo
static struct bp_location *
allocate_bp_location (struct breakpoint *bpt)
{
- struct bp_location *loc;
-
- if (bpt->ops && bpt->ops->allocate_location)
- return bpt->ops->allocate_location (bpt);
-
- loc = xmalloc (sizeof (struct bp_location));
- init_bp_location (loc, NULL, bpt);
- return loc;
+ return bpt->ops->allocate_location (bpt);
}

static void
free_bp_location (struct bp_location *loc)
{
- if (loc->ops && loc->ops->dtor)
- loc->ops->dtor (loc);
-
- if (loc->cond)
- xfree (loc->cond);
-
- if (loc->function_name)
- xfree (loc->function_name);
-
+ loc->ops->dtor (loc);
xfree (loc);
}

@@ -5830,6 +5517,8 @@ init_raw_breakpoint_without_location (st
{
memset (b, 0, sizeof (*b));

+ gdb_assert (ops != NULL);
+
b->ops = ops;
b->type = bptype;
b->gdbarch = gdbarch;
@@ -5849,16 +5538,15 @@ init_raw_breakpoint_without_location (st

/* Helper to set_raw_breakpoint below. Creates a breakpoint
that has type BPTYPE and has no locations as yet. */
-/* This function is used in gdbtk sources and thus can not be made
- static. */

static struct breakpoint *
set_raw_breakpoint_without_location (struct gdbarch *gdbarch,
- enum bptype bptype)
+ enum bptype bptype,
+ struct breakpoint_ops *ops)
{
struct breakpoint *b = XNEW (struct breakpoint);

- init_raw_breakpoint_without_location (b, gdbarch, bptype, NULL);
+ init_raw_breakpoint_without_location (b, gdbarch, bptype, ops);
add_to_breakpoint_chain (b);
return b;
}
@@ -5994,11 +5682,12 @@ init_raw_breakpoint (struct breakpoint *

struct breakpoint *
set_raw_breakpoint (struct gdbarch *gdbarch,
- struct symtab_and_line sal, enum bptype bptype)
+ struct symtab_and_line sal, enum bptype bptype,
+ struct breakpoint_ops *ops)
{
struct breakpoint *b = XNEW (struct breakpoint);

- init_raw_breakpoint (b, gdbarch, sal, bptype, NULL);
+ init_raw_breakpoint (b, gdbarch, sal, bptype, ops);
add_to_breakpoint_chain (b);
return b;
}
@@ -6341,9 +6030,10 @@ breakpoint_hit_catch_fork (const struct
catchpoints. */

static enum print_stop_action
-print_it_catch_fork (struct breakpoint *b)
+print_it_catch_fork (bpstat bs)
{
- struct fork_catchpoint *c = (struct fork_catchpoint *) b;
+ struct breakpoint *b = bs->breakpoint_at;
+ struct fork_catchpoint *c = (struct fork_catchpoint *) bs->breakpoint_at;

annotate_catchpoint (b->number);
printf_filtered (_("\nCatchpoint %d (forked process %d), "),
@@ -6400,18 +6090,18 @@ print_recreate_catch_fork (struct breakp

static struct breakpoint_ops catch_fork_breakpoint_ops =
{
- NULL, /* dtor */
- NULL, /* allocate_location */
- NULL, /* re_set */
+ bkpt_dtor,
+ bkpt_allocate_location,
+ null_re_set,
insert_catch_fork,
remove_catch_fork,
breakpoint_hit_catch_fork,
- NULL, /* check_status */
- NULL, /* resources_needed */
- NULL, /* works_in_software_mode */
+ null_check_status,
+ null_resources_needed,
+ null_works_in_software_mode,
print_it_catch_fork,
print_one_catch_fork,
- NULL, /* print_one_detail */
+ null_print_one_detail,
print_mention_catch_fork,
print_recreate_catch_fork
};
@@ -6450,8 +6140,9 @@ breakpoint_hit_catch_vfork (const struct
catchpoints. */

static enum print_stop_action
-print_it_catch_vfork (struct breakpoint *b)
+print_it_catch_vfork (bpstat bs)
{
+ struct breakpoint *b = bs->breakpoint_at;
struct fork_catchpoint *c = (struct fork_catchpoint *) b;

annotate_catchpoint (b->number);
@@ -6508,18 +6199,18 @@ print_recreate_catch_vfork (struct break

static struct breakpoint_ops catch_vfork_breakpoint_ops =
{
- NULL, /* dtor */
- NULL, /* allocate_location */
- NULL, /* re_set */
+ bkpt_dtor,
+ bkpt_allocate_location,
+ null_re_set,
insert_catch_vfork,
remove_catch_vfork,
breakpoint_hit_catch_vfork,
- NULL, /* check_status */
- NULL, /* resources_needed */
- NULL, /* works_in_software_mode */
+ null_check_status,
+ null_resources_needed,
+ null_works_in_software_mode,
print_it_catch_vfork,
print_one_catch_vfork,
- NULL, /* print_one_detail */
+ null_print_one_detail,
print_mention_catch_vfork,
print_recreate_catch_vfork
};
@@ -6675,8 +6366,9 @@ breakpoint_hit_catch_syscall (const stru
catchpoints. */

static enum print_stop_action
-print_it_catch_syscall (struct breakpoint *b)
+print_it_catch_syscall (bpstat bs)
{
+ struct breakpoint *b = bs->breakpoint_at;
/* These are needed because we want to know in which state a
syscall is. It can be in the TARGET_WAITKIND_SYSCALL_ENTRY
or TARGET_WAITKIND_SYSCALL_RETURN, and depending on it we
@@ -6838,17 +6530,17 @@ print_recreate_catch_syscall (struct bre
static struct breakpoint_ops catch_syscall_breakpoint_ops =
{
dtor_catch_syscall,
- NULL, /* allocate_location */
- NULL, /* re_set */
+ bkpt_allocate_location,
+ null_re_set,
insert_catch_syscall,
remove_catch_syscall,
breakpoint_hit_catch_syscall,
- NULL, /* check_status */
- NULL, /* resources_needed */
- NULL, /* works_in_software_mode */
+ null_check_status,
+ null_resources_needed,
+ null_works_in_software_mode,
print_it_catch_syscall,
print_one_catch_syscall,
- NULL, /* print_one_detail */
+ null_print_one_detail,
print_mention_catch_syscall,
print_recreate_catch_syscall
};
@@ -6960,8 +6652,9 @@ breakpoint_hit_catch_exec (const struct
}

static enum print_stop_action
-print_it_catch_exec (struct breakpoint *b)
+print_it_catch_exec (bpstat bs)
{
+ struct breakpoint *b = bs->breakpoint_at;
struct exec_catchpoint *c = (struct exec_catchpoint *) b;

annotate_catchpoint (b->number);
@@ -7011,17 +6704,17 @@ print_recreate_catch_exec (struct breakp
static struct breakpoint_ops catch_exec_breakpoint_ops =
{
dtor_catch_exec,
- NULL, /* allocate_location */
- NULL, /* re_set */
+ bkpt_allocate_location,
+ null_re_set,
insert_catch_exec,
remove_catch_exec,
breakpoint_hit_catch_exec,
- NULL, /* check_status */
- NULL, /* resources_needed */
- NULL, /* works_in_software_mode */
+ null_check_status,
+ null_resources_needed,
+ null_works_in_software_mode,
print_it_catch_exec,
print_one_catch_exec,
- NULL, /* print_one_detail */
+ null_print_one_detail,
print_mention_catch_exec,
print_recreate_catch_exec
};
@@ -7054,10 +6747,7 @@ hw_breakpoint_used_count (void)
{
/* Special types of hardware breakpoints may use more than
one register. */
- if (b->ops && b->ops->resources_needed)
- i += b->ops->resources_needed (bl);
- else
- i++;
+ i += b->ops->resources_needed (bl);
}
}

@@ -7082,10 +6772,7 @@ hw_watchpoint_used_count (enum bptype ty
{
/* Special types of hardware watchpoints may use more than
one register. */
- if (b->ops && b->ops->resources_needed)
- i += b->ops->resources_needed (bl);
- else
- i++;
+ i += b->ops->resources_needed (bl);
}
else if (is_hardware_watchpoint (b))
*other_type_used = 1;
@@ -7191,7 +6878,7 @@ set_momentary_breakpoint (struct gdbarch
one. */
gdb_assert (!frame_id_inlined_p (frame_id));

- b = set_raw_breakpoint (gdbarch, sal, type);
+ b = set_raw_breakpoint (gdbarch, sal, type, &bkpt_breakpoint_ops);
b->enable_state = bp_enabled;
b->disposition = disp_donttouch;
b->frame_id = frame_id;
@@ -7219,7 +6906,8 @@ clone_momentary_breakpoint (struct break
if (orig == NULL)
return NULL;

- copy = set_raw_breakpoint_without_location (orig->gdbarch, orig->type);
+ copy = set_raw_breakpoint_without_location (orig->gdbarch,
+ orig->type, orig->ops);
copy->loc = allocate_bp_location (copy);
set_breakpoint_location_function (copy->loc, 1);

@@ -7267,162 +6955,7 @@ set_momentary_breakpoint_at_pc (struct g
static void
mention (struct breakpoint *b)
{
- int say_where = 0;
- struct cleanup *ui_out_chain;
- struct value_print_options opts;
-
- get_user_print_options (&opts);
-
- if (b->ops != NULL && b->ops->print_mention != NULL)
- b->ops->print_mention (b);
- else
- switch (b->type)
- {
- case bp_none:
- printf_filtered (_("(apparently deleted?) Eventpoint %d: "),
- b->number);
- break;
- case bp_watchpoint:
- ui_out_text (uiout, "Watchpoint ");
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
- ui_out_field_int (uiout, "number", b->number);
- ui_out_text (uiout, ": ");
- ui_out_field_string (uiout, "exp", b->exp_string);
- do_cleanups (ui_out_chain);
- break;
- case bp_hardware_watchpoint:
- ui_out_text (uiout, "Hardware watchpoint ");
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
- ui_out_field_int (uiout, "number", b->number);
- ui_out_text (uiout, ": ");
- ui_out_field_string (uiout, "exp", b->exp_string);
- do_cleanups (ui_out_chain);
- break;
- case bp_read_watchpoint:
- ui_out_text (uiout, "Hardware read watchpoint ");
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
- ui_out_field_int (uiout, "number", b->number);
- ui_out_text (uiout, ": ");
- ui_out_field_string (uiout, "exp", b->exp_string);
- do_cleanups (ui_out_chain);
- break;
- case bp_access_watchpoint:
- ui_out_text (uiout, "Hardware access (read/write) watchpoint ");
- ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
- ui_out_field_int (uiout, "number", b->number);
- ui_out_text (uiout, ": ");
- ui_out_field_string (uiout, "exp", b->exp_string);
- do_cleanups (ui_out_chain);
- break;
- case bp_breakpoint:
- case bp_gnu_ifunc_resolver:
- if (ui_out_is_mi_like_p (uiout))
- {
- say_where = 0;
- break;
- }
- if (b->disposition == disp_del)
- printf_filtered (_("Temporary breakpoint"));
- else
- printf_filtered (_("Breakpoint"));
- printf_filtered (_(" %d"), b->number);
- if (b->type == bp_gnu_ifunc_resolver)
- printf_filtered (_(" at gnu-indirect-function resolver"));
- say_where = 1;
- break;
- case bp_hardware_breakpoint:
- if (ui_out_is_mi_like_p (uiout))
- {
- say_where = 0;
- break;
- }
- printf_filtered (_("Hardware assisted breakpoint %d"), b->number);
- say_where = 1;
- break;
- case bp_tracepoint:
- if (ui_out_is_mi_like_p (uiout))
- {
- say_where = 0;
- break;
- }
- printf_filtered (_("Tracepoint"));
- printf_filtered (_(" %d"), b->number);
- say_where = 1;
- break;
- case bp_fast_tracepoint:
- if (ui_out_is_mi_like_p (uiout))
- {
- say_where = 0;
- break;
- }
- printf_filtered (_("Fast tracepoint"));
- printf_filtered (_(" %d"), b->number);
- say_where = 1;
- break;
- case bp_static_tracepoint:
- if (ui_out_is_mi_like_p (uiout))
- {
- say_where = 0;
- break;
- }
- printf_filtered (_("Static tracepoint"));
- printf_filtered (_(" %d"), b->number);
- say_where = 1;
- break;
-
- case bp_until:
- case bp_finish:
- case bp_longjmp:
- case bp_longjmp_resume:
- case bp_exception:
- case bp_exception_resume:
- case bp_step_resume:
- case bp_hp_step_resume:
- case bp_call_dummy:
- case bp_std_terminate:
- case bp_watchpoint_scope:
- case bp_shlib_event:
- case bp_thread_event:
- case bp_overlay_event:
- case bp_jit_event:
- case bp_longjmp_master:
- case bp_std_terminate_master:
- case bp_exception_master:
- case bp_gnu_ifunc_resolver_return:
- break;
- }
-
- if (say_where)
- {
- /* i18n: cagney/2005-02-11: Below needs to be merged into a
- single string. */
- if (b->loc == NULL)
- {
- printf_filtered (_(" (%s) pending."), b->addr_string);
- }
- else
- {
- if (opts.addressprint || b->source_file == NULL)
- {
- printf_filtered (" at ");
- fputs_filtered (paddress (b->loc->gdbarch, b->loc->address),
- gdb_stdout);
- }
- if (b->source_file)
- printf_filtered (": file %s, line %d.",
- b->source_file, b->line_number);
-
- if (b->loc->next)
- {
- struct bp_location *loc = b->loc;
- int n = 0;
- for (; loc; loc = loc->next)
- ++n;
- printf_filtered (" (%d locations)", n);
- }
-
- }
- }
+ b->ops->print_mention (b);
if (ui_out_is_mi_like_p (uiout))
return;
printf_filtered ("\n");
@@ -7545,7 +7078,7 @@ create_breakpoint_sal (struct gdbarch *g

if (i == 0)
{
- b = set_raw_breakpoint (gdbarch, sal, type);
+ b = set_raw_breakpoint (gdbarch, sal, type, ops);
set_breakpoint_number (internal, b);
b->thread = thread;
b->task = task;
@@ -7627,7 +7160,6 @@ create_breakpoint_sal (struct gdbarch *g
b->addr_string
= xstrprintf ("*%s", paddress (b->loc->gdbarch, b->loc->address));

- b->ops = ops;
/* Do not mention breakpoints with a negative number, but do
notify observers. */
if (!internal)
@@ -8085,6 +7617,8 @@ create_breakpoint (struct gdbarch *gdbar
int task = 0;
int prev_bkpt_count = breakpoint_count;

+ gdb_assert (ops != NULL);
+
sals.sals = NULL;
sals.nelts = 0;
init_linespec_result (&canonical);
@@ -8277,7 +7811,7 @@ create_breakpoint (struct gdbarch *gdbar

make_cleanup (xfree, copy_arg);

- b = set_raw_breakpoint_without_location (gdbarch, type_wanted);
+ b = set_raw_breakpoint_without_location (gdbarch, type_wanted, ops);
set_breakpoint_number (internal, b);
b->thread = -1;
b->addr_string = canonical.canonical[0];
@@ -8285,7 +7819,6 @@ create_breakpoint (struct gdbarch *gdbar
b->ignore_count = ignore_count;
b->disposition = tempflag ? disp_del : disp_donttouch;
b->condition_not_parsed = 1;
- b->ops = ops;
b->enable_state = enabled ? bp_enabled : bp_disabled;
b->pspace = current_program_space;
b->py_bp_object = NULL;
@@ -8321,13 +7854,13 @@ create_breakpoint (struct gdbarch *gdbar
return 1;
}

-/* Set a breakpoint.
+/* Set a breakpoint.
ARG is a string describing breakpoint address,
condition, and thread.
FLAG specifies if a breakpoint is hardware on,
and if breakpoint is temporary, using BP_HARDWARE_FLAG
and BP_TEMPFLAG. */
-
+
static void
break_command_1 (char *arg, int flag, int from_tty)
{
@@ -8342,13 +7875,12 @@ break_command_1 (char *arg, int flag, in
tempflag, type_wanted,
0 /* Ignore count */,
pending_break_support,
- NULL /* breakpoint_ops */,
+ &bkpt_breakpoint_ops,
from_tty,
1 /* enabled */,
0 /* internal */);
}

-
/* Helper function for break_command_1 and disassemble_command. */

void
@@ -8528,8 +8060,9 @@ resources_needed_ranged_breakpoint (cons
ranged breakpoints. */

static enum print_stop_action
-print_it_ranged_breakpoint (struct breakpoint *b)
+print_it_ranged_breakpoint (bpstat bs)
{
+ struct breakpoint *b = bs->breakpoint_at;
struct bp_location *bl = b->loc;

gdb_assert (b->type == bp_hardware_breakpoint);
@@ -8638,15 +8171,15 @@ print_recreate_ranged_breakpoint (struct

static struct breakpoint_ops ranged_breakpoint_ops =
{
- NULL, /* dtor */
- NULL, /* allocate_location */
- NULL, /* re_set */
- NULL, /* insert */
- NULL, /* remove */
+ bkpt_dtor,
+ bkpt_allocate_location,
+ bkpt_re_set,
+ bkpt_insert_location,
+ bkpt_remove_location,
breakpoint_hit_ranged_breakpoint,
- NULL, /* check_status */
+ null_check_status,
resources_needed_ranged_breakpoint,
- NULL, /* works_in_software_mode */
+ null_works_in_software_mode,
print_it_ranged_breakpoint,
print_one_ranged_breakpoint,
print_one_detail_ranged_breakpoint,
@@ -8796,13 +8329,12 @@ break_range_command (char *arg, int from

/* Now set up the breakpoint. */
b = set_raw_breakpoint (get_current_arch (), sal_start,
- bp_hardware_breakpoint);
+ bp_hardware_breakpoint, &ranged_breakpoint_ops);
set_breakpoint_count (breakpoint_count + 1);
b->number = breakpoint_count;
b->disposition = disp_donttouch;
b->addr_string = addr_string_start;
b->addr_string_range_end = addr_string_end;
- b->ops = &ranged_breakpoint_ops;
b->loc->length = length;

discard_cleanups (cleanup_bkpt);
@@ -8921,6 +8453,39 @@ watchpoint_exp_is_const (const struct ex
return 1;
}

+/* Implement the "re_set" breakpoint_ops method for watchpoints. */
+
+static void
+re_set_watchpoint (struct breakpoint *b)
+{
+ /* Watchpoint can be either on expression using entirely global
+ variables, or it can be on local variables.
+
+ Watchpoints of the first kind are never auto-deleted, and even
+ persist across program restarts. Since they can use variables
+ from shared libraries, we need to reparse expression as libraries
+ are loaded and unloaded.
+
+ Watchpoints on local variables can also change meaning as result
+ of solib event. For example, if a watchpoint uses both a local
+ and a global variables in expression, it's a local watchpoint,
+ but unloading of a shared library will make the expression
+ invalid. This is not a very common use case, but we still
+ re-evaluate expression, to avoid surprises to the user.
+
+ Note that for local watchpoints, we re-evaluate it only if
+ watchpoints frame id is still valid. If it's not, it means the
+ watchpoint is out of scope and will be deleted soon. In fact,
+ I'm not sure we'll ever be called in this case.
+
+ If a local watchpoint's frame id is still valid, then
+ b->exp_valid_block is likewise valid, and we can safely use it.
+
+ Don't do anything about disabled watchpoints, since they will
+ be reevaluated again when enabled. */
+ update_watchpoint (b, 1 /* reparse */);
+}
+
/* Implement the "insert" breakpoint_ops method for hardware watchpoints. */

static int
@@ -8943,102 +8508,90 @@ remove_watchpoint (struct bp_location *b
bl->owner->cond_exp);
}

-/* Implement the "resources_needed" breakpoint_ops method for
- hardware watchpoints. */
-
static int
-resources_needed_watchpoint (const struct bp_location *bl)
+breakpoint_hit_watchpoint (const struct bp_location *bl,
+ struct address_space *aspace, CORE_ADDR bp_addr)
{
- int length = bl->owner->exact? 1 : bl->length;
-
- return target_region_ok_for_hw_watchpoint (bl->address, length);
-}
+ struct breakpoint *b = bl->owner;

-/* Implement the "works_in_software_mode" breakpoint_ops method for
- hardware watchpoints. */
+ /* Continuable hardware watchpoints are treated as non-existent if the
+ reason we stopped wasn't a hardware watchpoint (we didn't stop on
+ some data address). Otherwise gdb won't stop on a break instruction
+ in the code (not from a breakpoint) when a hardware watchpoint has
+ been defined. Also skip watchpoints which we know did not trigger
+ (did not match the data address). */
+ if (is_hardware_watchpoint (b)
+ && b->watchpoint_triggered == watch_triggered_no)
+ return 0;

-int
-works_in_software_mode_watchpoint (const struct breakpoint *b)
-{
- return b->type == bp_hardware_watchpoint;
+ return 1;
}

-/* The breakpoint_ops structure to be used in hardware watchpoints. */
-
-static struct breakpoint_ops watchpoint_breakpoint_ops =
-{
- NULL, /* dtor */
- NULL, /* allocate_location */
- NULL, /* re_set */
- insert_watchpoint,
- remove_watchpoint,
- NULL, /* breakpoint_hit */
- NULL, /* check_status */
- resources_needed_watchpoint,
- works_in_software_mode_watchpoint,
- NULL, /* print_it */
- NULL, /* print_one */
- NULL, /* print_one_detail */
- NULL, /* print_mention */
- NULL /* print_recreate */
-};
-
-/* Implement the "insert" breakpoint_ops method for
- masked hardware watchpoints. */
-
-static int
-insert_masked_watchpoint (struct bp_location *bl)
+static void
+check_status_watchpoint (bpstat bs)
{
- return target_insert_mask_watchpoint (bl->address, bl->owner->hw_wp_mask,
- bl->watchpoint_type);
-}
-
-/* Implement the "remove" breakpoint_ops method for
- masked hardware watchpoints. */
+ gdb_assert (is_watchpoint (bs->breakpoint_at));

-static int
-remove_masked_watchpoint (struct bp_location *bl)
-{
- return target_remove_mask_watchpoint (bl->address, bl->owner->hw_wp_mask,
- bl->watchpoint_type);
+ bpstat_check_watchpoint (bs);
}

/* Implement the "resources_needed" breakpoint_ops method for
- masked hardware watchpoints. */
+ hardware watchpoints. */

static int
-resources_needed_masked_watchpoint (const struct bp_location *bl)
+resources_needed_watchpoint (const struct bp_location *bl)
{
- return target_masked_watch_num_registers (bl->address,
- bl->owner->hw_wp_mask);
+ int length = bl->owner->exact? 1 : bl->length;
+
+ return target_region_ok_for_hw_watchpoint (bl->address, length);
}

/* Implement the "works_in_software_mode" breakpoint_ops method for
- masked hardware watchpoints. */
+ hardware watchpoints. */

static int
-works_in_software_mode_masked_watchpoint (const struct breakpoint *b)
+works_in_software_mode_watchpoint (const struct breakpoint *b)
{
- return 0;
+ return b->type == bp_hardware_watchpoint;
}

-/* Implement the "print_it" breakpoint_ops method for
- masked hardware watchpoints. */
-
static enum print_stop_action
-print_it_masked_watchpoint (struct breakpoint *b)
+print_it_watchpoint (bpstat bs)
{
- /* Masked watchpoints have only one location. */
- gdb_assert (b->loc && b->loc->next == NULL);
+ struct cleanup *old_chain;
+ struct breakpoint *b;
+ const struct bp_location *bl;
+ struct ui_stream *stb;
+ enum print_stop_action result;
+
+ gdb_assert (bs->bp_location_at != NULL);
+
+ bl = bs->bp_location_at;
+ b = bs->breakpoint_at;
+
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup_ui_out_stream_delete (stb);

switch (b->type)
{
+ case bp_watchpoint:
case bp_hardware_watchpoint:
annotate_watchpoint (b->number);
if (ui_out_is_mi_like_p (uiout))
ui_out_field_string
(uiout, "reason",
async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
+ mention (b);
+ make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+ ui_out_text (uiout, "\nOld value = ");
+ watchpoint_value_print (bs->old_val, stb->stream);
+ ui_out_field_stream (uiout, "old", stb);
+ ui_out_text (uiout, "\nNew value = ");
+ watchpoint_value_print (b->val, stb->stream);
+ ui_out_field_stream (uiout, "new", stb);
+ ui_out_text (uiout, "\n");
+ /* More than one watchpoint may have been triggered. */
+ result = PRINT_UNKNOWN;
break;

case bp_read_watchpoint:
@@ -9046,26 +8599,223 @@ print_it_masked_watchpoint (struct break
ui_out_field_string
(uiout, "reason",
async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
+ mention (b);
+ make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+ ui_out_text (uiout, "\nValue = ");
+ watchpoint_value_print (b->val, stb->stream);
+ ui_out_field_stream (uiout, "value", stb);
+ ui_out_text (uiout, "\n");
+ result = PRINT_UNKNOWN;
break;

case bp_access_watchpoint:
- if (ui_out_is_mi_like_p (uiout))
- ui_out_field_string
- (uiout, "reason",
- async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
+ if (bs->old_val != NULL)
+ {
+ annotate_watchpoint (b->number);
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
+ mention (b);
+ make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+ ui_out_text (uiout, "\nOld value = ");
+ watchpoint_value_print (bs->old_val, stb->stream);
+ ui_out_field_stream (uiout, "old", stb);
+ ui_out_text (uiout, "\nNew value = ");
+ }
+ else
+ {
+ mention (b);
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
+ make_cleanup_ui_out_tuple_begin_end (uiout, "value");
+ ui_out_text (uiout, "\nValue = ");
+ }
+ watchpoint_value_print (b->val, stb->stream);
+ ui_out_field_stream (uiout, "new", stb);
+ ui_out_text (uiout, "\n");
+ result = PRINT_UNKNOWN;
break;
default:
- internal_error (__FILE__, __LINE__,
- _("Invalid hardware watchpoint type."));
+ result = PRINT_UNKNOWN;
}

- mention (b);
- ui_out_text (uiout, _("\n\
-Check the underlying instruction at PC for the memory\n\
-address and value which triggered this watchpoint.\n"));
- ui_out_text (uiout, "\n");
-
- /* More than one watchpoint may have been triggered. */
+ do_cleanups (old_chain);
+ return result;
+}
+
+/* Implement the "print_mention" breakpoint_ops method for hardware
+ watchpoints. */
+
+static void
+print_mention_watchpoint (struct breakpoint *b)
+{
+ struct cleanup *ui_out_chain;
+
+ switch (b->type)
+ {
+ case bp_watchpoint:
+ ui_out_text (uiout, "Watchpoint ");
+ ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
+ break;
+ case bp_hardware_watchpoint:
+ ui_out_text (uiout, "Hardware watchpoint ");
+ ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt");
+ break;
+ case bp_read_watchpoint:
+ ui_out_text (uiout, "Hardware read watchpoint ");
+ ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt");
+ break;
+ case bp_access_watchpoint:
+ ui_out_text (uiout, "Hardware access (read/write) watchpoint ");
+ ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt");
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("Invalid hardware watchpoint type."));
+ }
+
+ ui_out_field_int (uiout, "number", b->number);
+ ui_out_text (uiout, ": ");
+ ui_out_field_string (uiout, "exp", b->exp_string);
+ do_cleanups (ui_out_chain);
+}
+
+/* Implement the "print_recreate" breakpoint_ops method for
+ watchpoints. */
+
+static void
+print_recreate_watchpoint (struct breakpoint *b, struct ui_file *fp)
+{
+ char tmp[40];
+
+ switch (b->type)
+ {
+ case bp_watchpoint:
+ case bp_hardware_watchpoint:
+ fprintf_unfiltered (fp, "watch");
+ break;
+ case bp_read_watchpoint:
+ fprintf_unfiltered (fp, "rwatch");
+ break;
+ case bp_access_watchpoint:
+ fprintf_unfiltered (fp, "awatch");
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("Invalid watchpoint type."));
+ }
+
+ fprintf_unfiltered (fp, " %s", b->exp_string);
+}
+
+/* The breakpoint_ops structure to be used in hardware watchpoints. */
+
+static struct breakpoint_ops watchpoint_breakpoint_ops =
+{
+ bkpt_dtor,
+ bkpt_allocate_location,
+ re_set_watchpoint,
+ insert_watchpoint,
+ remove_watchpoint,
+ breakpoint_hit_watchpoint,
+ check_status_watchpoint,
+ resources_needed_watchpoint,
+ works_in_software_mode_watchpoint,
+ print_it_watchpoint,
+ NULL, /* print_one */
+ null_print_one_detail,
+ print_mention_watchpoint,
+ print_recreate_watchpoint
+};
+
+/* Implement the "insert" breakpoint_ops method for
+ masked hardware watchpoints. */
+
+static int
+insert_masked_watchpoint (struct bp_location *bl)
+{
+ return target_insert_mask_watchpoint (bl->address, bl->owner->hw_wp_mask,
+ bl->watchpoint_type);
+}
+
+/* Implement the "remove" breakpoint_ops method for
+ masked hardware watchpoints. */
+
+static int
+remove_masked_watchpoint (struct bp_location *bl)
+{
+ return target_remove_mask_watchpoint (bl->address, bl->owner->hw_wp_mask,
+ bl->watchpoint_type);
+}
+
+/* Implement the "resources_needed" breakpoint_ops method for
+ masked hardware watchpoints. */
+
+static int
+resources_needed_masked_watchpoint (const struct bp_location *bl)
+{
+ return target_masked_watch_num_registers (bl->address,
+ bl->owner->hw_wp_mask);
+}
+
+/* Implement the "works_in_software_mode" breakpoint_ops method for
+ masked hardware watchpoints. */
+
+static int
+works_in_software_mode_masked_watchpoint (const struct breakpoint *b)
+{
+ return 0;
+}
+
+/* Implement the "print_it" breakpoint_ops method for
+ masked hardware watchpoints. */
+
+static enum print_stop_action
+print_it_masked_watchpoint (bpstat bs)
+{
+ struct breakpoint *b = bs->breakpoint_at;
+
+ /* Masked watchpoints have only one location. */
+ gdb_assert (b->loc && b->loc->next == NULL);
+
+ switch (b->type)
+ {
+ case bp_hardware_watchpoint:
+ annotate_watchpoint (b->number);
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_WATCHPOINT_TRIGGER));
+ break;
+
+ case bp_read_watchpoint:
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_READ_WATCHPOINT_TRIGGER));
+ break;
+
+ case bp_access_watchpoint:
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_ACCESS_WATCHPOINT_TRIGGER));
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("Invalid hardware watchpoint type."));
+ }
+
+ mention (b);
+ ui_out_text (uiout, _("\n\
+Check the underlying instruction at PC for the memory\n\
+address and value which triggered this watchpoint.\n"));
+ ui_out_text (uiout, "\n");
+
+ /* More than one watchpoint may have been triggered. */
return PRINT_UNKNOWN;
}

@@ -9149,13 +8899,13 @@ print_recreate_masked_watchpoint (struct

static struct breakpoint_ops masked_watchpoint_breakpoint_ops =
{
- NULL, /* dtor */
- NULL, /* allocate_location */
- NULL, /* re_set */
+ bkpt_dtor,
+ bkpt_allocate_location,
+ re_set_watchpoint,
insert_masked_watchpoint,
remove_masked_watchpoint,
- NULL, /* breakpoint_hit */
- NULL, /* check_status */
+ breakpoint_hit_watchpoint,
+ check_status_watchpoint,
resources_needed_masked_watchpoint,
works_in_software_mode_masked_watchpoint,
print_it_masked_watchpoint,
@@ -9394,12 +9144,18 @@ watch_command_1 (char *arg, int accessfl
}

/* Now set up the breakpoint. */
- b = set_raw_breakpoint_without_location (NULL, bp_type);
+ if (use_mask)
+ b = set_raw_breakpoint_without_location (NULL, bp_type,
+ &masked_watchpoint_breakpoint_ops);
+ else
+ b = set_raw_breakpoint_without_location (NULL, bp_type,
+ &watchpoint_breakpoint_ops);
b->thread = thread;
b->disposition = disp_donttouch;
b->exp = exp;
b->exp_valid_block = exp_valid_block;
b->cond_exp_valid_block = cond_exp_valid_block;
+ b->pspace = current_program_space;
if (just_location)
{
struct type *t = value_type (val);
@@ -9425,13 +9181,11 @@ watch_command_1 (char *arg, int accessfl
if (use_mask)
{
b->hw_wp_mask = mask;
- b->ops = &masked_watchpoint_breakpoint_ops;
}
else
{
b->val = val;
b->val_valid = 1;
- b->ops = &watchpoint_breakpoint_ops;
}

if (cond_start)
@@ -9881,8 +9635,9 @@ catch_exec_command_1 (char *arg, int fro
}

static enum print_stop_action
-print_it_exception_catchpoint (struct breakpoint *b)
+print_it_exception_catchpoint (bpstat bs)
{
+ struct breakpoint *b = bs->breakpoint_at;
int bp_temp, bp_throw;

annotate_catchpoint (b->number);
@@ -9968,18 +9723,18 @@ print_recreate_exception_catchpoint (str
}

static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
- NULL, /* dtor */
- NULL, /* allocate_location */
- NULL, /* re_set */
- NULL, /* insert */
- NULL, /* remove */
- NULL, /* breakpoint_hit */
- NULL, /* check_status */
- NULL, /* resources_needed */
- NULL, /* works_in_software_mode */
+ bkpt_dtor,
+ bkpt_allocate_location,
+ bkpt_re_set,
+ bkpt_insert_location,
+ bkpt_remove_location,
+ bkpt_breakpoint_hit,
+ bkpt_check_status,
+ bkpt_resources_needed,
+ null_works_in_software_mode,
print_it_exception_catchpoint,
print_one_exception_catchpoint,
- NULL, /* print_one_detail */
+ null_print_one_detail,
print_mention_exception_catchpoint,
print_recreate_exception_catchpoint
};
@@ -10678,127 +10433,730 @@ update_global_location_list (int should_
}
}

- /* Rescan breakpoints at the same address and section, marking the
- first one as "first" and any others as "duplicates". This is so
- that the bpt instruction is only inserted once. If we have a
- permanent breakpoint at the same place as BPT, make that one the
- official one, and the rest as duplicates. Permanent breakpoints
- are sorted first for the same address.
-
- Do the same for hardware watchpoints, but also considering the
- watchpoint's type (regular/access/read) and length. */
+ /* Rescan breakpoints at the same address and section, marking the
+ first one as "first" and any others as "duplicates". This is so
+ that the bpt instruction is only inserted once. If we have a
+ permanent breakpoint at the same place as BPT, make that one the
+ official one, and the rest as duplicates. Permanent breakpoints
+ are sorted first for the same address.
+
+ Do the same for hardware watchpoints, but also considering the
+ watchpoint's type (regular/access/read) and length. */
+
+ bp_loc_first = NULL;
+ wp_loc_first = NULL;
+ awp_loc_first = NULL;
+ rwp_loc_first = NULL;
+ ALL_BP_LOCATIONS (loc, locp)
+ {
+ /* ALL_BP_LOCATIONS bp_location has LOC->OWNER always
+ non-NULL. */
+ struct breakpoint *b = loc->owner;
+ struct bp_location **loc_first_p;
+
+ if (b->enable_state == bp_disabled
+ || b->enable_state == bp_call_disabled
+ || b->enable_state == bp_startup_disabled
+ || !loc->enabled
+ || loc->shlib_disabled
+ || !breakpoint_address_is_meaningful (b)
+ || is_tracepoint (b))
+ continue;
+
+ /* Permanent breakpoint should always be inserted. */
+ if (b->enable_state == bp_permanent && ! loc->inserted)
+ internal_error (__FILE__, __LINE__,
+ _("allegedly permanent breakpoint is not "
+ "actually inserted"));
+
+ if (b->type == bp_hardware_watchpoint)
+ loc_first_p = &wp_loc_first;
+ else if (b->type == bp_read_watchpoint)
+ loc_first_p = &rwp_loc_first;
+ else if (b->type == bp_access_watchpoint)
+ loc_first_p = &awp_loc_first;
+ else
+ loc_first_p = &bp_loc_first;
+
+ if (*loc_first_p == NULL
+ || (overlay_debugging && loc->section != (*loc_first_p)->section)
+ || !breakpoint_locations_match (loc, *loc_first_p))
+ {
+ *loc_first_p = loc;
+ loc->duplicate = 0;
+ continue;
+ }
+
+ loc->duplicate = 1;
+
+ if ((*loc_first_p)->owner->enable_state == bp_permanent && loc->inserted
+ && b->enable_state != bp_permanent)
+ internal_error (__FILE__, __LINE__,
+ _("another breakpoint was inserted on top of "
+ "a permanent breakpoint"));
+ }
+
+ if (breakpoints_always_inserted_mode () && should_insert
+ && (have_live_inferiors ()
+ || (gdbarch_has_global_breakpoints (target_gdbarch))))
+ insert_breakpoint_locations ();
+
+ do_cleanups (cleanups);
+}
+
+void
+breakpoint_retire_moribund (void)
+{
+ struct bp_location *loc;
+ int ix;
+
+ for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
+ if (--(loc->events_till_retirement) == 0)
+ {
+ decref_bp_location (&loc);
+ VEC_unordered_remove (bp_location_p, moribund_locations, ix);
+ --ix;
+ }
+}
+
+static void
+update_global_location_list_nothrow (int inserting)
+{
+ struct gdb_exception e;
+
+ TRY_CATCH (e, RETURN_MASK_ERROR)
+ update_global_location_list (inserting);
+}
+
+/* Clear BKP from a BPS. */
+
+static void
+bpstat_remove_bp_location (bpstat bps, struct breakpoint *bpt)
+{
+ bpstat bs;
+
+ for (bs = bps; bs; bs = bs->next)
+ if (bs->breakpoint_at == bpt)
+ {
+ bs->breakpoint_at = NULL;
+ bs->old_val = NULL;
+ /* bs->commands will be freed later. */
+ }
+}
+
+/* Callback for iterate_over_threads. */
+static int
+bpstat_remove_breakpoint_callback (struct thread_info *th, void *data)
+{
+ struct breakpoint *bpt = data;
+
+ bpstat_remove_bp_location (th->control.stop_bpstat, bpt);
+ return 0;
+}
+
+/* Helper for breakpoint and tracepoint breakpoint_ops->mention
+ callbacks. */
+
+static void
+say_where (struct breakpoint *b)
+{
+ struct value_print_options opts;
+
+ get_user_print_options (&opts);
+
+ /* i18n: cagney/2005-02-11: Below needs to be merged into a
+ single string. */
+ if (b->loc == NULL)
+ {
+ printf_filtered (_(" (%s) pending."), b->addr_string);
+ }
+ else
+ {
+ if (opts.addressprint || b->source_file == NULL)
+ {
+ printf_filtered (" at ");
+ fputs_filtered (paddress (b->loc->gdbarch, b->loc->address),
+ gdb_stdout);
+ }
+ if (b->source_file)
+ printf_filtered (": file %s, line %d.",
+ b->source_file, b->line_number);
+
+ if (b->loc->next)
+ {
+ struct bp_location *loc = b->loc;
+ int n = 0;
+ for (; loc; loc = loc->next)
+ ++n;
+ printf_filtered (" (%d locations)", n);
+ }
+ }
+}
+
+/* Default breakpoint_ops methods that do nothing. */
+
+void
+null_re_set (struct breakpoint *b)
+{
+ /* Nothing to re-set. */
+}
+
+void
+null_check_status (bpstat bs)
+{
+ /* nothing */
+}
+
+/* A "works_in_software_mode" breakpoint_ops method that just internal
+ errors. */
+
+int
+null_works_in_software_mode (const struct breakpoint *b)
+{
+ gdb_assert_not_reached ("");
+}
+
+/* A "resources_needed" breakpoint_ops method that just internal
+ errors. */
+
+int
+null_resources_needed (const struct bp_location *bl)
+{
+ gdb_assert_not_reached ("");
+}
+
+void
+null_print_one_detail (const struct breakpoint *self,
+ struct ui_out *uiout)
+{
+ /* nothing */
+}
+
+/* Default bp_location_ops methods. */
+
+static void
+bp_location_dtor (struct bp_location *self)
+{
+ xfree (self->cond);
+ xfree (self->function_name);
+}
+
+static const struct bp_location_ops bp_location_ops =
+{
+ bp_location_dtor
+};
+
+/* Default breakpoint_ops methods. */
+
+void
+bkpt_dtor (struct breakpoint *self)
+{
+ decref_counted_command_line (&self->commands);
+ xfree (self->cond_string);
+ xfree (self->cond_exp);
+ xfree (self->addr_string);
+ xfree (self->addr_string_range_end);
+ xfree (self->exp);
+ xfree (self->exp_string);
+ xfree (self->exp_string_reparse);
+ value_free (self->val);
+ xfree (self->source_file);
+}
+
+struct bp_location *
+bkpt_allocate_location (struct breakpoint *self)
+{
+ struct bp_location *loc;
+
+ loc = XNEW (struct bp_location);
+ init_bp_location (loc, &bp_location_ops, self);
+ return loc;
+}
+
+void
+bkpt_re_set (struct breakpoint *b)
+{
+ switch (b->type)
+ {
+ case bp_breakpoint:
+ case bp_hardware_breakpoint:
+ case bp_gnu_ifunc_resolver:
+ /* Do not attempt to re-set breakpoints disabled during
+ startup. */
+ if (b->enable_state == bp_startup_disabled)
+ return;
+
+ if (b->addr_string == NULL)
+ {
+ /* Anything without a string can't be re-set. */
+ delete_breakpoint (b);
+ return;
+ }
+
+ breakpoint_re_set_default (b);
+ break;
+
+ default:
+ printf_filtered (_("Deleting unknown breakpoint type %d\n"), b->type);
+ /* fall through */
+ /* Delete overlay event and longjmp master breakpoints; they
+ will be reset later by breakpoint_re_set. */
+ case bp_overlay_event:
+ case bp_longjmp_master:
+ case bp_std_terminate_master:
+ case bp_exception_master:
+ delete_breakpoint (b);
+ break;
+
+ /* This breakpoint is special, it's set up when the inferior
+ starts and we really don't want to touch it. */
+ case bp_shlib_event:
+
+ /* Like bp_shlib_event, this breakpoint type is special. Once
+ it is set up, we do not want to touch it. */
+ case bp_thread_event:
+
+ /* Keep temporary breakpoints, which can be encountered when we
+ step over a dlopen call and SOLIB_ADD is resetting the
+ breakpoints. Otherwise these should have been blown away via
+ the cleanup chain or by breakpoint_init_inferior when we
+ rerun the executable. */
+ case bp_until:
+ case bp_finish:
+ case bp_watchpoint_scope:
+ case bp_call_dummy:
+ case bp_std_terminate:
+ case bp_step_resume:
+ case bp_hp_step_resume:
+ case bp_longjmp:
+ case bp_longjmp_resume:
+ case bp_exception:
+ case bp_exception_resume:
+ case bp_jit_event:
+ case bp_gnu_ifunc_resolver_return:
+ break;
+ }
+}
+
+int
+bkpt_insert_location (struct bp_location *bl)
+{
+ if (bl->loc_type == bp_loc_hardware_breakpoint)
+ return target_insert_hw_breakpoint (bl->gdbarch,
+ &bl->target_info);
+ else
+ return target_insert_breakpoint (bl->gdbarch,
+ &bl->target_info);
+}
+
+int
+bkpt_remove_location (struct bp_location *bl)
+{
+ if (bl->loc_type == bp_loc_hardware_breakpoint)
+ return target_remove_hw_breakpoint (bl->gdbarch, &bl->target_info);
+ else
+ return target_remove_breakpoint (bl->gdbarch, &bl->target_info);
+}
+
+int
+bkpt_breakpoint_hit (const struct bp_location *bl,
+ struct address_space *aspace, CORE_ADDR bp_addr)
+{
+ struct breakpoint *b = bl->owner;
+
+ if (!breakpoint_address_match (bl->pspace->aspace, bl->address,
+ aspace, bp_addr))
+ return 0;
+
+ if (overlay_debugging /* unmapped overlay section */
+ && section_is_overlay (bl->section)
+ && !section_is_mapped (bl->section))
+ return 0;
+
+ return 1;
+}
+
+void
+bkpt_check_status (bpstat bs)
+{
+ struct breakpoint *b = bs->breakpoint_at;
+
+ if (b->type == bp_thread_event
+ || b->type == bp_overlay_event
+ || b->type == bp_longjmp_master
+ || b->type == bp_std_terminate_master
+ || b->type == bp_exception_master)
+ /* We do not stop for these. */
+ bs->stop = 0;
+}
+
+int
+bkpt_resources_needed (const struct bp_location *bl)
+{
+ gdb_assert (bl->owner->type == bp_hardware_breakpoint);
+
+ return 1;
+}
+
+int
+bkpt_works_in_software_mode (const struct breakpoint *b)
+{
+ gdb_assert_not_reached ("");
+}
+
+enum print_stop_action
+bkpt_print_it (bpstat bs)
+{
+ struct cleanup *old_chain;
+ struct breakpoint *b;
+ const struct bp_location *bl;
+ struct ui_stream *stb;
+ int bp_temp = 0;
+ enum print_stop_action result;
+
+ gdb_assert (bs->bp_location_at != NULL);
+
+ bl = bs->bp_location_at;
+ b = bs->breakpoint_at;
+
+ stb = ui_out_stream_new (uiout);
+ old_chain = make_cleanup_ui_out_stream_delete (stb);
+
+ switch (b->type)
+ {
+ case bp_breakpoint:
+ case bp_hardware_breakpoint:
+ bp_temp = b->disposition == disp_del;
+ if (bl->address != bl->requested_address)
+ breakpoint_adjustment_warning (bl->requested_address,
+ bl->address,
+ b->number, 1);
+ annotate_breakpoint (b->number);
+ if (bp_temp)
+ ui_out_text (uiout, "\nTemporary breakpoint ");
+ else
+ ui_out_text (uiout, "\nBreakpoint ");
+ if (ui_out_is_mi_like_p (uiout))
+ {
+ ui_out_field_string (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
+ ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+ }
+ ui_out_field_int (uiout, "bkptno", b->number);
+ ui_out_text (uiout, ", ");
+ result = PRINT_SRC_AND_LOC;
+ break;
+
+ case bp_shlib_event:
+ /* Did we stop because the user set the stop_on_solib_events
+ variable? (If so, we report this as a generic, "Stopped due
+ to shlib event" message.) */
+ printf_filtered (_("Stopped due to shared library event\n"));
+ result = PRINT_NOTHING;
+ break;
+
+ case bp_thread_event:
+ /* Not sure how we will get here.
+ GDB should not stop for these breakpoints. */
+ printf_filtered (_("Thread Event Breakpoint: gdb should not stop!\n"));
+ result = PRINT_NOTHING;
+ break;
+
+ case bp_overlay_event:
+ /* By analogy with the thread event, GDB should not stop for these. */
+ printf_filtered (_("Overlay Event Breakpoint: gdb should not stop!\n"));
+ result = PRINT_NOTHING;
+ break;
+
+ case bp_longjmp_master:
+ /* These should never be enabled. */
+ printf_filtered (_("Longjmp Master Breakpoint: gdb should not stop!\n"));
+ result = PRINT_NOTHING;
+ break;
+
+ case bp_std_terminate_master:
+ /* These should never be enabled. */
+ printf_filtered (_("std::terminate Master Breakpoint: "
+ "gdb should not stop!\n"));
+ result = PRINT_NOTHING;
+ break;
+
+ case bp_exception_master:
+ /* These should never be enabled. */
+ printf_filtered (_("Exception Master Breakpoint: "
+ "gdb should not stop!\n"));
+ result = PRINT_NOTHING;
+ break;
+
+ /* Fall through, we don't deal with these types of breakpoints
+ here. */
+
+ case bp_finish:
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_FUNCTION_FINISHED));
+ result = PRINT_UNKNOWN;
+ break;
+
+ case bp_until:
+ if (ui_out_is_mi_like_p (uiout))
+ ui_out_field_string
+ (uiout, "reason",
+ async_reason_lookup (EXEC_ASYNC_LOCATION_REACHED));
+ result = PRINT_UNKNOWN;
+ break;
+
+ case bp_none:
+ case bp_longjmp:
+ case bp_longjmp_resume:
+ case bp_exception:
+ case bp_exception_resume:
+ case bp_step_resume:
+ case bp_hp_step_resume:
+ case bp_watchpoint_scope:
+ case bp_call_dummy:
+ case bp_std_terminate:
+ case bp_tracepoint:
+ case bp_fast_tracepoint:
+ case bp_jit_event:
+ case bp_gnu_ifunc_resolver:
+ case bp_gnu_ifunc_resolver_return:
+ default:
+ result = PRINT_UNKNOWN;
+ break;
+ }
+
+ do_cleanups (old_chain);
+ return result;
+}
+
+void
+bkpt_print_mention (struct breakpoint *b)
+{
+ if (ui_out_is_mi_like_p (uiout))
+ return;
+
+ switch (b->type)
+ {
+ case bp_breakpoint:
+ case bp_gnu_ifunc_resolver:
+ if (b->disposition == disp_del)
+ printf_filtered (_("Temporary breakpoint"));
+ else
+ printf_filtered (_("Breakpoint"));
+ printf_filtered (_(" %d"), b->number);
+ if (b->type == bp_gnu_ifunc_resolver)
+ printf_filtered (_(" at gnu-indirect-function resolver"));
+ say_where (b);
+ break;
+ case bp_hardware_breakpoint:
+ printf_filtered (_("Hardware assisted breakpoint %d"), b->number);
+ say_where (b);
+ break;
+ case bp_until:
+ case bp_finish:
+ case bp_longjmp:
+ case bp_longjmp_resume:
+ case bp_exception:
+ case bp_exception_resume:
+ case bp_step_resume:
+ case bp_hp_step_resume:
+ case bp_call_dummy:
+ case bp_std_terminate:
+ case bp_watchpoint_scope:
+ case bp_shlib_event:
+ case bp_thread_event:
+ case bp_overlay_event:
+ case bp_jit_event:
+ case bp_longjmp_master:
+ case bp_std_terminate_master:
+ case bp_exception_master:
+ case bp_gnu_ifunc_resolver_return:
+ break;
+ }
+}
+
+void
+bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp)
+{
+ if (tp->type == bp_breakpoint && tp->disposition == disp_del)
+ fprintf_unfiltered (fp, "tbreak");
+ else if (tp->type == bp_breakpoint)
+ fprintf_unfiltered (fp, "break");
+ else if (tp->type == bp_hardware_breakpoint
+ && tp->disposition == disp_del)
+ fprintf_unfiltered (fp, "thbreak");
+ else if (tp->type == bp_hardware_breakpoint)
+ fprintf_unfiltered (fp, "hbreak");
+ else
+ internal_error (__FILE__, __LINE__,
+ _("unhandled breakpoint type %d"), (int) tp->type);

- bp_loc_first = NULL;
- wp_loc_first = NULL;
- awp_loc_first = NULL;
- rwp_loc_first = NULL;
- ALL_BP_LOCATIONS (loc, locp)
+ if (tp->exp_string)
+ fprintf_unfiltered (fp, " %s", tp->exp_string);
+ else if (tp->addr_string)
+ fprintf_unfiltered (fp, " %s", tp->addr_string);
+ else
{
- /* ALL_BP_LOCATIONS bp_location has LOC->OWNER always
- non-NULL. */
- struct breakpoint *b = loc->owner;
- struct bp_location **loc_first_p;
+ char tmp[40];

- if (b->enable_state == bp_disabled
- || b->enable_state == bp_call_disabled
- || b->enable_state == bp_startup_disabled
- || !loc->enabled
- || loc->shlib_disabled
- || !breakpoint_address_is_meaningful (b)
- || is_tracepoint (b))
- continue;
+ sprintf_vma (tmp, tp->loc->address);
+ fprintf_unfiltered (fp, " *0x%s", tmp);
+ }
+}

- /* Permanent breakpoint should always be inserted. */
- if (b->enable_state == bp_permanent && ! loc->inserted)
- internal_error (__FILE__, __LINE__,
- _("allegedly permanent breakpoint is not "
- "actually inserted"));
+/* The breakpoint_ops structure to be used in regular breakpoints. */

- if (b->type == bp_hardware_watchpoint)
- loc_first_p = &wp_loc_first;
- else if (b->type == bp_read_watchpoint)
- loc_first_p = &rwp_loc_first;
- else if (b->type == bp_access_watchpoint)
- loc_first_p = &awp_loc_first;
- else
- loc_first_p = &bp_loc_first;
+struct breakpoint_ops bkpt_breakpoint_ops =
+{
+ bkpt_dtor,
+ bkpt_allocate_location,
+ bkpt_re_set,
+ bkpt_insert_location,
+ bkpt_remove_location,
+ bkpt_breakpoint_hit,
+ bkpt_check_status,
+ bkpt_resources_needed,
+ null_works_in_software_mode,
+ bkpt_print_it,
+ NULL, /* print_one */
+ null_print_one_detail,
+ bkpt_print_mention,
+ bkpt_print_recreate
+};

- if (*loc_first_p == NULL
- || (overlay_debugging && loc->section != (*loc_first_p)->section)
- || !breakpoint_locations_match (loc, *loc_first_p))
- {
- *loc_first_p = loc;
- loc->duplicate = 0;
- continue;
- }
+/* The breakpoint_ops structure to be used in tracepoints. */

- loc->duplicate = 1;
+void
+tracepoint_re_set (struct breakpoint *b)
+{
+ breakpoint_re_set_default (b);
+}

- if ((*loc_first_p)->owner->enable_state == bp_permanent && loc->inserted
- && b->enable_state != bp_permanent)
- internal_error (__FILE__, __LINE__,
- _("another breakpoint was inserted on top of "
- "a permanent breakpoint"));
- }
+static int
+tracepoint_insert_location (struct bp_location *bl)
+{
+ gdb_assert_not_reached ("");
+}

- if (breakpoints_always_inserted_mode () && should_insert
- && (have_live_inferiors ()
- || (gdbarch_has_global_breakpoints (target_gdbarch))))
- insert_breakpoint_locations ();
+static int
+tracepoint_remove_location (struct bp_location *bl)
+{
+ gdb_assert_not_reached ("");
+}

- do_cleanups (cleanups);
+static int
+tracepoint_breakpoint_hit (const struct bp_location *bl,
+ struct address_space *aspace, CORE_ADDR bp_addr)
+{
+ /* By definition, the inferior does not report stops at
+ tracepoints. */
+ return 0;
}

-void
-breakpoint_retire_moribund (void)
+static void
+tracepoint_check_status (bpstat bs)
{
- struct bp_location *loc;
- int ix;
+ gdb_assert_not_reached ("");
+}

- for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix)
- if (--(loc->events_till_retirement) == 0)
- {
- decref_bp_location (&loc);
- VEC_unordered_remove (bp_location_p, moribund_locations, ix);
- --ix;
- }
+static int
+tracepoint_works_in_software_mode (const struct breakpoint *b)
+{
+ gdb_assert_not_reached ("");
+}
+
+static enum print_stop_action
+tracepoint_print_it (bpstat bs)
+{
+ gdb_assert_not_reached ("");
}

static void
-update_global_location_list_nothrow (int inserting)
+tracepoint_print_one_detail (const struct breakpoint *self,
+ struct ui_out *uiout)
{
- struct gdb_exception e;
+ if (self->static_trace_marker_id)
+ {
+ gdb_assert (self->type == bp_static_tracepoint);

- TRY_CATCH (e, RETURN_MASK_ERROR)
- update_global_location_list (inserting);
+ ui_out_text (uiout, "\tmarker id is ");
+ ui_out_field_string (uiout, "static-tracepoint-marker-string-id",
+ self->static_trace_marker_id);
+ ui_out_text (uiout, "\n");
+ }
}

-/* Clear BKP from a BPS. */
-
static void
-bpstat_remove_bp_location (bpstat bps, struct breakpoint *bpt)
+tracepoint_print_mention (struct breakpoint *b)
{
- bpstat bs;
+ if (ui_out_is_mi_like_p (uiout))
+ return;

- for (bs = bps; bs; bs = bs->next)
- if (bs->breakpoint_at == bpt)
- {
- bs->breakpoint_at = NULL;
- bs->old_val = NULL;
- /* bs->commands will be freed later. */
- }
+ switch (b->type)
+ {
+ case bp_tracepoint:
+ printf_filtered (_("Tracepoint"));
+ printf_filtered (_(" %d"), b->number);
+ break;
+ case bp_fast_tracepoint:
+ printf_filtered (_("Fast tracepoint"));
+ printf_filtered (_(" %d"), b->number);
+ break;
+ case bp_static_tracepoint:
+ printf_filtered (_("Static tracepoint"));
+ printf_filtered (_(" %d"), b->number);
+ break;
+ }
+
+ say_where (b);
}

-/* Callback for iterate_over_threads. */
-static int
-bpstat_remove_breakpoint_callback (struct thread_info *th, void *data)
+static void
+tracepoint_print_recreate (struct breakpoint *tp, struct ui_file *fp)
{
- struct breakpoint *bpt = data;
+ if (tp->type == bp_fast_tracepoint)
+ fprintf_unfiltered (fp, "ftrace");
+ if (tp->type == bp_static_tracepoint)
+ fprintf_unfiltered (fp, "strace");
+ else if (tp->type == bp_tracepoint)
+ fprintf_unfiltered (fp, "trace");
+ else
+ internal_error (__FILE__, __LINE__,
+ _("unhandled tracepoint type %d"), (int) tp->type);

- bpstat_remove_bp_location (th->control.stop_bpstat, bpt);
- return 0;
+ if (tp->exp_string)
+ fprintf_unfiltered (fp, " %s", tp->exp_string);
+ else if (tp->addr_string)
+ fprintf_unfiltered (fp, " %s", tp->addr_string);
+ else
+ {
+ char tmp[40];
+
+ sprintf_vma (tmp, tp->loc->address);
+ fprintf_unfiltered (fp, " *0x%s", tmp);
+ }
}

+struct breakpoint_ops tracepoint_breakpoint_ops =
+{
+ bkpt_dtor,
+ bkpt_allocate_location,
+ tracepoint_re_set,
+ tracepoint_insert_location,
+ tracepoint_remove_location,
+ tracepoint_breakpoint_hit,
+ tracepoint_check_status,
+ null_resources_needed,
+ tracepoint_works_in_software_mode,
+ tracepoint_print_it,
+ NULL, /* print_one */
+ tracepoint_print_one_detail,
+ tracepoint_print_mention,
+ tracepoint_print_recreate
+};
+
/* Delete a breakpoint and clean up all traces of it in the data
structures. */

@@ -10863,21 +11221,6 @@ delete_breakpoint (struct breakpoint *bp
break;
}

- if (bpt->ops != NULL && bpt->ops->dtor != NULL)
- bpt->ops->dtor (bpt);
-
- decref_counted_command_line (&bpt->commands);
- xfree (bpt->cond_string);
- xfree (bpt->cond_exp);
- xfree (bpt->addr_string);
- xfree (bpt->addr_string_range_end);
- xfree (bpt->exp);
- xfree (bpt->exp_string);
- xfree (bpt->exp_string_reparse);
- value_free (bpt->val);
- xfree (bpt->source_file);
-
-
/* Be sure no bpstat's are pointing at the breakpoint after it's
been freed. */
/* FIXME, how can we find all bpstat's? We just check stop_bpstat
@@ -10898,11 +11241,10 @@ delete_breakpoint (struct breakpoint *bp
self-contained, but it's not the case now. */
update_global_location_list (0);

-
+ 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;
-
xfree (bpt);
}

@@ -11421,7 +11763,11 @@ addr_string_to_sals (struct breakpoint *
return sals;
}

-void
+/* The default re_set method, for typical hardware or software
+ breakpoints. Reevaluate the breakpoint and recreate its
+ locations. */
+
+static void
breakpoint_re_set_default (struct breakpoint *b)
{
int found;
@@ -11473,129 +11819,11 @@ breakpoint_re_set_one (void *bint)
{
/* Get past catch_errs. */
struct breakpoint *b = (struct breakpoint *) bint;
+ struct cleanup *cleanups;

- if (b->ops != NULL && b->ops->re_set != NULL)
- {
- struct cleanup *cleanups;
-
- cleanups = prepare_re_set_context (b);
- b->ops->re_set (b);
- do_cleanups (cleanups);
-
- return 0;
- }
-
- switch (b->type)
- {
- case bp_none:
- warning (_("attempted to reset apparently deleted breakpoint #%d?"),
- b->number);
- return 0;
- case bp_breakpoint:
- case bp_hardware_breakpoint:
- case bp_tracepoint:
- case bp_fast_tracepoint:
- case bp_static_tracepoint:
- case bp_gnu_ifunc_resolver:
- /* Do not attempt to re-set breakpoints disabled during startup. */
- if (b->enable_state == bp_startup_disabled)
- return 0;
-
- if (b->addr_string == NULL)
- {
- /* Anything without a string can't be re-set. */
- delete_breakpoint (b);
- return 0;
- }
-
- {
- struct cleanup *cleanups;
-
- cleanups = prepare_re_set_context (b);
- breakpoint_re_set_default (b);
- do_cleanups (cleanups);
- }
- break;
-
- case bp_watchpoint:
- case bp_hardware_watchpoint:
- case bp_read_watchpoint:
- case bp_access_watchpoint:
- /* Watchpoint can be either on expression using entirely global
- variables, or it can be on local variables.
-
- Watchpoints of the first kind are never auto-deleted, and
- even persist across program restarts. Since they can use
- variables from shared libraries, we need to reparse
- expression as libraries are loaded and unloaded.
-
- Watchpoints on local variables can also change meaning as
- result of solib event. For example, if a watchpoint uses
- both a local and a global variables in expression, it's a
- local watchpoint, but unloading of a shared library will make
- the expression invalid. This is not a very common use case,
- but we still re-evaluate expression, to avoid surprises to
- the user.
-
- Note that for local watchpoints, we re-evaluate it only if
- watchpoints frame id is still valid. If it's not, it means
- the watchpoint is out of scope and will be deleted soon. In
- fact, I'm not sure we'll ever be called in this case.
-
- If a local watchpoint's frame id is still valid, then
- b->exp_valid_block is likewise valid, and we can safely use it.
-
- Don't do anything about disabled watchpoints, since they will
- be reevaluated again when enabled. */
- update_watchpoint (b, 1 /* reparse */);
- break;
- /* We needn't really do anything to reset these, since the mask
- that requests them is unaffected by e.g., new libraries being
- loaded. */
- case bp_catchpoint:
- break;
-
- default:
- printf_filtered (_("Deleting unknown breakpoint type %d\n"), b->type);
- /* fall through */
- /* Delete overlay event and longjmp master breakpoints; they will be
- reset later by breakpoint_re_set. */
- case bp_overlay_event:
- case bp_longjmp_master:
- case bp_std_terminate_master:
- case bp_exception_master:
- delete_breakpoint (b);
- break;
-
- /* This breakpoint is special, it's set up when the inferior
- starts and we really don't want to touch it. */
- case bp_shlib_event:
-
- /* Like bp_shlib_event, this breakpoint type is special.
- Once it is set up, we do not want to touch it. */
- case bp_thread_event:
-
- /* Keep temporary breakpoints, which can be encountered when we
- step over a dlopen call and SOLIB_ADD is resetting the
- breakpoints. Otherwise these should have been blown away via
- the cleanup chain or by breakpoint_init_inferior when we
- rerun the executable. */
- case bp_until:
- case bp_finish:
- case bp_watchpoint_scope:
- case bp_call_dummy:
- case bp_std_terminate:
- case bp_step_resume:
- case bp_hp_step_resume:
- case bp_longjmp:
- case bp_longjmp_resume:
- case bp_exception:
- case bp_exception_resume:
- case bp_jit_event:
- case bp_gnu_ifunc_resolver_return:
- break;
- }
-
+ cleanups = prepare_re_set_context (b);
+ b->ops->re_set (b);
+ do_cleanups (cleanups);
return 0;
}

@@ -12347,7 +12575,7 @@ trace_command (char *arg, int from_tty)
bp_tracepoint /* type_wanted */,
0 /* Ignore count */,
pending_break_support,
- NULL,
+ &tracepoint_breakpoint_ops,
from_tty,
1 /* enabled */,
0 /* internal */))
@@ -12364,7 +12592,7 @@ ftrace_command (char *arg, int from_tty)
bp_fast_tracepoint /* type_wanted */,
0 /* Ignore count */,
pending_break_support,
- NULL,
+ &tracepoint_breakpoint_ops,
from_tty,
1 /* enabled */,
0 /* internal */))
@@ -12383,7 +12611,7 @@ strace_command (char *arg, int from_tty)
bp_static_tracepoint /* type_wanted */,
0 /* Ignore count */,
pending_break_support,
- NULL,
+ &tracepoint_breakpoint_ops,
from_tty,
1 /* enabled */,
0 /* internal */))
@@ -12448,7 +12676,7 @@ create_tracepoint_from_upload (struct up
utp->type /* type_wanted */,
0 /* Ignore count */,
pending_break_support,
- NULL,
+ &tracepoint_breakpoint_ops,
0 /* from_tty */,
utp->enabled /* enabled */,
0 /* internal */))
@@ -12774,49 +13002,7 @@ save_breakpoints (char *filename, int fr
if (filter && !filter (tp))
continue;

- if (tp->ops != NULL && tp->ops->print_recreate != NULL)
- (tp->ops->print_recreate) (tp, fp);
- else
- {
- if (tp->type == bp_fast_tracepoint)
- fprintf_unfiltered (fp, "ftrace");
- if (tp->type == bp_static_tracepoint)
- fprintf_unfiltered (fp, "strace");
- else if (tp->type == bp_tracepoint)
- fprintf_unfiltered (fp, "trace");
- else if (tp->type == bp_breakpoint && tp->disposition == disp_del)
- fprintf_unfiltered (fp, "tbreak");
- else if (tp->type == bp_breakpoint)
- fprintf_unfiltered (fp, "break");
- else if (tp->type == bp_hardware_breakpoint
- && tp->disposition == disp_del)
- fprintf_unfiltered (fp, "thbreak");
- else if (tp->type == bp_hardware_breakpoint)
- fprintf_unfiltered (fp, "hbreak");
- else if (tp->type == bp_watchpoint)
- fprintf_unfiltered (fp, "watch");
- else if (tp->type == bp_hardware_watchpoint)
- fprintf_unfiltered (fp, "watch");
- else if (tp->type == bp_read_watchpoint)
- fprintf_unfiltered (fp, "rwatch");
- else if (tp->type == bp_access_watchpoint)
- fprintf_unfiltered (fp, "awatch");
- else
- internal_error (__FILE__, __LINE__,
- _("unhandled breakpoint type %d"), (int) tp->type);
-
- if (tp->exp_string)
- fprintf_unfiltered (fp, " %s", tp->exp_string);
- else if (tp->addr_string)
- fprintf_unfiltered (fp, " %s", tp->addr_string);
- else
- {
- char tmp[40];
-
- sprintf_vma (tmp, tp->loc->address);
- fprintf_unfiltered (fp, " *0x%s", tmp);
- }
- }
+ tp->ops->print_recreate (tp, fp);

if (tp->thread != -1)
fprintf_unfiltered (fp, " thread %d", tp->thread);
Index: src/gdb/ada-lang.c
===================================================================
--- src.orig/gdb/ada-lang.c 2011-06-22 18:52:55.000000000 +0100
+++ src/gdb/ada-lang.c 2011-06-24 17:04:42.348082956 +0100
@@ -10860,6 +10860,8 @@ dtor_exception (enum exception_catchpoin
struct ada_catchpoint *c = (struct ada_catchpoint *) b;

xfree (c->excep_string);
+
+ bkpt_dtor (b);
}

/* Implement the ALLOCATE_LOCATION method in the breakpoint_ops
@@ -10887,7 +10889,7 @@ re_set_exception (enum exception_catchpo

/* Call the base class's method. This updates the catchpoint's
locations. */
- breakpoint_re_set_default (b);
+ bkpt_re_set (b);

/* Reparse the exception conditional expressions. One for each
location. */
@@ -10946,8 +10948,10 @@ check_status_exception (enum exception_c
for all exception catchpoint kinds. */

static enum print_stop_action
-print_it_exception (enum exception_catchpoint_kind ex, struct breakpoint *b)
+print_it_exception (enum exception_catchpoint_kind ex, bpstat bs)
{
+ struct breakpoint *b = bs->breakpoint_at;
+
annotate_catchpoint (b->number);

if (ui_out_is_mi_like_p (uiout))
@@ -11149,9 +11153,9 @@ check_status_catch_exception (bpstat bs)
}

static enum print_stop_action
-print_it_catch_exception (struct breakpoint *b)
+print_it_catch_exception (bpstat bs)
{
- return print_it_exception (ex_catch_exception, b);
+ return print_it_exception (ex_catch_exception, bs);
}

static void
@@ -11177,15 +11181,15 @@ static struct breakpoint_ops catch_excep
dtor_catch_exception,
allocate_location_catch_exception,
re_set_catch_exception,
- NULL, /* insert */
- NULL, /* remove */
- NULL, /* breakpoint_hit */
+ bkpt_insert_location,
+ bkpt_remove_location,
+ bkpt_breakpoint_hit,
check_status_catch_exception,
- NULL, /* resources_needed */
- NULL, /* works_in_software_mode */
+ bkpt_resources_needed,
+ null_works_in_software_mode,
print_it_catch_exception,
print_one_catch_exception,
- NULL, /* print_one_detail */
+ null_print_one_detail,
print_mention_catch_exception,
print_recreate_catch_exception
};
@@ -11217,9 +11221,9 @@ check_status_catch_exception_unhandled (
}

static enum print_stop_action
-print_it_catch_exception_unhandled (struct breakpoint *b)
+print_it_catch_exception_unhandled (bpstat bs)
{
- return print_it_exception (ex_catch_exception_unhandled, b);
+ return print_it_exception (ex_catch_exception_unhandled, bs);
}

static void
@@ -11246,15 +11250,15 @@ static struct breakpoint_ops catch_excep
dtor_catch_exception_unhandled,
allocate_location_catch_exception_unhandled,
re_set_catch_exception_unhandled,
- NULL, /* insert */
- NULL, /* remove */
- NULL, /* breakpoint_hit */
+ bkpt_insert_location,
+ bkpt_remove_location,
+ bkpt_breakpoint_hit,
check_status_catch_exception_unhandled,
- NULL, /* resources_needed */
- NULL, /* works_in_software_mode */
+ bkpt_resources_needed,
+ null_works_in_software_mode,
print_it_catch_exception_unhandled,
print_one_catch_exception_unhandled,
- NULL, /* print_one_detail */
+ null_print_one_detail,
print_mention_catch_exception_unhandled,
print_recreate_catch_exception_unhandled
};
@@ -11286,9 +11290,9 @@ check_status_catch_assert (bpstat bs)
}

static enum print_stop_action
-print_it_catch_assert (struct breakpoint *b)
+print_it_catch_assert (bpstat bs)
{
- return print_it_exception (ex_catch_assert, b);
+ return print_it_exception (ex_catch_assert, bs);
}

static void
@@ -11313,15 +11317,15 @@ static struct breakpoint_ops catch_asser
dtor_catch_assert,
allocate_location_catch_assert,
re_set_catch_assert,
- NULL, /* insert */
- NULL, /* remove */
- NULL, /* breakpoint_hit */
+ bkpt_insert_location,
+ bkpt_remove_location,
+ bkpt_breakpoint_hit,
check_status_catch_assert,
- NULL, /* resources_needed */
- NULL, /* works_in_software_mode */
+ bkpt_resources_needed,
+ null_works_in_software_mode,
print_it_catch_assert,
print_one_catch_assert,
- NULL, /* print_one_detail */
+ null_print_one_detail,
print_mention_catch_assert,
print_recreate_catch_assert
};
Index: src/gdb/breakpoint.h
===================================================================
--- src.orig/gdb/breakpoint.h 2011-06-22 18:52:55.000000000 +0100
+++ src/gdb/breakpoint.h 2011-06-24 17:27:56.988082476 +0100
@@ -422,8 +422,8 @@ struct breakpoint_ops
void (*re_set) (struct breakpoint *self);

/* Insert the breakpoint or watchpoint or activate the catchpoint.
- Return 0 for success, 1 if the breakpoint, watchpoint or catchpoint
- type is not supported, -1 for failure. */
+ Return 0 for success, 1 if the breakpoint, watchpoint or
+ catchpoint type is not supported, -1 for failure. */
int (*insert_location) (struct bp_location *);

/* Remove the breakpoint/catchpoint that was previously inserted
@@ -454,7 +454,7 @@ struct breakpoint_ops

/* The normal print routine for this breakpoint, called when we
hit it. */
- enum print_stop_action (*print_it) (struct breakpoint *);
+ enum print_stop_action (*print_it) (struct bpstats *bs);

/* Display information about this breakpoint, for "info
breakpoints". */
@@ -801,9 +801,19 @@ struct bpstat_what
print_it_done, print_it_noop. */
enum print_stop_action
{
+ /* We printed nothing or we need to do some more analysis. */
PRINT_UNKNOWN = -1,
+
+ /* We printed something, and we *do* desire that something to be
+ followed by a location. */
PRINT_SRC_AND_LOC,
+
+ /* We printed something, and we do *not* desire that something to
+ be followed by a location. */
PRINT_SRC_ONLY,
+
+ /* We already printed all we needed to print, don't print anything
+ else. */
PRINT_NOTHING
};

@@ -980,12 +990,6 @@ extern void breakpoint_re_set (void);

extern void breakpoint_re_set_thread (struct breakpoint *);

-/* The default re_set method, for typical hardware or software
- breakpoints. Reevaluate the breakpoint and recreate its
- locations. */
-
-extern void breakpoint_re_set_default (struct breakpoint *);
-
extern struct breakpoint *set_momentary_breakpoint
(struct gdbarch *, struct symtab_and_line, struct frame_id, enum bptype);

@@ -1025,6 +1029,32 @@ extern void awatch_command_wrapper (char
extern void rwatch_command_wrapper (char *, int, int);
extern void tbreak_command (char *, int);

+extern void null_re_set (struct breakpoint *b);
+extern int null_works_in_software_mode (const struct breakpoint *b);
+extern int null_resources_needed (const struct bp_location *bl);
+extern void null_check_status (bpstat bs);
+extern void null_print_one_detail (const struct breakpoint *self,
+ struct ui_out *uiout);
+
+extern struct breakpoint_ops bkpt_breakpoint_ops;
+
+extern void bkpt_dtor (struct breakpoint *self);
+extern struct bp_location *bkpt_allocate_location (struct breakpoint *self);
+extern void bkpt_re_set (struct breakpoint *b);
+extern int bkpt_insert_location (struct bp_location *bl);
+extern int bkpt_remove_location (struct bp_location *bl);
+extern int bkpt_breakpoint_hit (const struct bp_location *bl,
+ struct address_space *aspace,
+ CORE_ADDR bp_addr);
+extern void bkpt_check_status (bpstat bs);
+extern int bkpt_resources_needed (const struct bp_location *bl);
+extern int bkpt_works_in_software_mode (const struct breakpoint *b);
+extern enum print_stop_action bkpt_print_it (bpstat bs);
+extern void null_print_one_detail (const struct breakpoint *self,
+ struct ui_out *uiout);
+extern void bkpt_print_mention (struct breakpoint *b);
+extern void bkpt_print_recreate (struct breakpoint *tp, struct ui_file *fp);
+
/* Arguments to pass as context to some catch command handlers. */
#define CATCH_PERMANENT ((void *) (uintptr_t) 0)
#define CATCH_TEMPORARY ((void *) (uintptr_t) 1)
Index: src/gdb/mi/mi-cmd-break.c
===================================================================
--- src.orig/gdb/mi/mi-cmd-break.c 2011-04-27 12:26:59.000000000 +0100
+++ src/gdb/mi/mi-cmd-break.c 2011-06-24 15:54:42.148084408 +0100
@@ -169,7 +169,7 @@ mi_cmd_break_insert (char *command, char
temp_p, type_wanted,
ignore_count,
pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
- NULL, 0, enabled, 0);
+ &bkpt_breakpoint_ops, 0, enabled, 0);
do_cleanups (back_to);

}
Index: src/gdb/python/py-breakpoint.c
===================================================================
--- src.orig/gdb/python/py-breakpoint.c 2011-04-27 13:08:51.000000000 +0100
+++ src/gdb/python/py-breakpoint.c 2011-06-24 15:55:01.898084401 +0100
@@ -633,7 +633,8 @@ bppy_init (PyObject *self, PyObject *arg
0, bp_breakpoint,
0,
AUTO_BOOLEAN_TRUE,
- NULL, 0, 1, internal_bp);
+ &bkpt_breakpoint_ops,
+ 0, 1, internal_bp);
break;
}