aboutsummaryrefslogtreecommitdiff
path: root/gdb/breakpoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r--gdb/breakpoint.c103
1 files changed, 88 insertions, 15 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 931f433..8f09296 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -1558,7 +1558,10 @@ in which its expression is valid.\n"),
/* Returns 1 iff breakpoint location should be
- inserted in the inferior. */
+ inserted in the inferior. We don't differentiate the type of BL's owner
+ (breakpoint vs. tracepoint), although insert_location in tracepoint's
+ breakpoint_ops is not defined, because in insert_bp_location,
+ tracepoint's insert_location will not be called. */
static int
should_be_inserted (struct bp_location *bl)
{
@@ -1582,11 +1585,6 @@ should_be_inserted (struct bp_location *bl)
if (bl->pspace->breakpoints_not_allowed)
return 0;
- /* Tracepoints are inserted by the target at a time of its choosing,
- not by us. */
- if (is_tracepoint (bl->owner))
- return 0;
-
return 1;
}
@@ -2052,7 +2050,7 @@ remove_breakpoints (void)
ALL_BP_LOCATIONS (bl, blp_tmp)
{
- if (bl->inserted)
+ if (bl->inserted && !is_tracepoint (bl->owner))
val |= remove_breakpoint (bl, mark_uninserted);
}
return val;
@@ -5446,6 +5444,23 @@ breakpoint_location_address_match (struct bp_location *bl,
aspace, addr)));
}
+/* If LOC1 and LOC2's owners are not tracepoints, returns false directly.
+ Then, if LOC1 and LOC2 represent the same tracepoint location, returns
+ true, otherwise returns false. */
+
+static int
+tracepoint_locations_match (struct bp_location *loc1,
+ struct bp_location *loc2)
+{
+ if (is_tracepoint (loc1->owner) && is_tracepoint (loc2->owner))
+ /* Since tracepoint locations are never duplicated with others', tracepoint
+ locations at the same address of different tracepoints are regarded as
+ different locations. */
+ return (loc1->address == loc2->address && loc1->owner == loc2->owner);
+ else
+ return 0;
+}
+
/* Assuming LOC1 and LOC2's types' have meaningful target addresses
(breakpoint_address_is_meaningful), returns true if LOC1 and LOC2
represent the same location. */
@@ -5467,6 +5482,8 @@ breakpoint_locations_match (struct bp_location *loc1,
return 0;
else if (hw_point1)
return watchpoint_locations_match (loc1, loc2);
+ else if (is_tracepoint (loc1->owner) || is_tracepoint (loc2->owner))
+ return tracepoint_locations_match (loc1, loc2);
else
/* We compare bp_location.length in order to cover ranged breakpoints. */
return (breakpoint_address_match (loc1->pspace->aspace, loc1->address,
@@ -6050,8 +6067,8 @@ disable_breakpoints_in_shlibs (void)
}
}
-/* Disable any breakpoints that are in an unloaded shared library.
- Only apply to enabled breakpoints, disabled ones can just stay
+/* Disable any breakpoints and tracepoints that are in an unloaded shared
+ library. Only apply to enabled breakpoints, disabled ones can just stay
disabled. */
static void
@@ -6073,13 +6090,14 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
/* ALL_BP_LOCATIONS bp_location has LOC->OWNER always non-NULL. */
struct breakpoint *b = loc->owner;
- if ((loc->loc_type == bp_loc_hardware_breakpoint
- || loc->loc_type == bp_loc_software_breakpoint)
- && solib->pspace == loc->pspace
+ if (solib->pspace == loc->pspace
&& !loc->shlib_disabled
- && (b->type == bp_breakpoint
- || b->type == bp_jit_event
- || b->type == bp_hardware_breakpoint)
+ && (((b->type == bp_breakpoint
+ || b->type == bp_jit_event
+ || b->type == bp_hardware_breakpoint)
+ && (loc->loc_type == bp_loc_hardware_breakpoint
+ || loc->loc_type == bp_loc_software_breakpoint))
+ || is_tracepoint (b))
&& solib_contains_address_p (solib, loc->address))
{
loc->shlib_disabled = 1;
@@ -10315,6 +10333,49 @@ bp_location_target_extensions_update (void)
}
}
+/* Download tracepoint locations if they haven't been. */
+
+static void
+download_tracepoint_locations (void)
+{
+ struct bp_location *bl, **blp_tmp;
+ struct cleanup *old_chain;
+
+ if (!target_can_download_tracepoint ())
+ return;
+
+ old_chain = save_current_space_and_thread ();
+
+ ALL_BP_LOCATIONS (bl, blp_tmp)
+ {
+ struct tracepoint *t;
+
+ if (!is_tracepoint (bl->owner))
+ continue;
+
+ if ((bl->owner->type == bp_fast_tracepoint
+ ? !may_insert_fast_tracepoints
+ : !may_insert_tracepoints))
+ continue;
+
+ /* In tracepoint, locations are _never_ duplicated, so
+ should_be_inserted is equivalent to
+ unduplicated_should_be_inserted. */
+ if (!should_be_inserted (bl) || bl->inserted)
+ continue;
+
+ switch_to_program_space_and_thread (bl->pspace);
+
+ target_download_tracepoint (bl);
+
+ bl->inserted = 1;
+ t = (struct tracepoint *) bl->owner;
+ t->number_on_target = bl->owner->number;
+ }
+
+ do_cleanups (old_chain);
+}
+
/* Swap the insertion/duplication state between two locations. */
static void
@@ -10324,6 +10385,12 @@ swap_insertion (struct bp_location *left, struct bp_location *right)
const int left_duplicate = left->duplicate;
const struct bp_target_info left_target_info = left->target_info;
+ /* Locations of tracepoints can never be duplicated. */
+ if (is_tracepoint (left->owner))
+ gdb_assert (!left->duplicate);
+ if (is_tracepoint (right->owner))
+ gdb_assert (!right->duplicate);
+
left->inserted = right->inserted;
left->duplicate = right->duplicate;
left->target_info = right->target_info;
@@ -10603,6 +10670,9 @@ update_global_location_list (int should_insert)
|| !loc->enabled
|| loc->shlib_disabled
|| !breakpoint_address_is_meaningful (b)
+ /* Don't detect duplicate for tracepoint locations because they are
+ never duplicated. See the comments in field `duplicate' of
+ `struct bp_location'. */
|| is_tracepoint (b))
continue;
@@ -10650,6 +10720,9 @@ update_global_location_list (int should_insert)
|| (gdbarch_has_global_breakpoints (target_gdbarch))))
insert_breakpoint_locations ();
+ if (should_insert)
+ download_tracepoint_locations ();
+
do_cleanups (cleanups);
}