* remote.c (struct remote_state): <install_in_trace> new field.
	(PACKET_InstallInTrace): New enum value.
	(remote_install_in_trace_feature): Support InstallInTrace.
	(remote_supports_install_in_trace): Likewise.
	(remote_protocol_features): Likewise.
	(_initialize_remote): Likewise.
	(remote_can_download_tracepoint): New.
	* target.h (struct target): New field
	`to_can_download_tracepoint'.
	(target_can_download_tracepoint): New macro.
	* target.c (update_current_target): Update.
	* breakpoint.h (struct bp_location): Add comment on field
	`duplicate'.
	(should_be_inserted): Don't differentiate breakpoint and tracepoint.
	(remove_breakpoints): Don't remove tracepoints.
	(tracepoint_locations_match ): New.
	(breakpoint_locations_match): Call it.
	(disable_breakpoints_in_unloaded_shlib): Handle tracepoint.
	(download_tracepoint_locations): New.
	(update_global_location_list): Call it.
	* tracepoint.c (find_matching_tracepoint): Delete.
	(find_matching_tracepoint_location): Renamed from
	find_matching_tracepoint.  Return bp_location rather than
	tracepoint.
	(merge_uploaded_tracepoints): Set `inserted' field to 1 if
	tracepoint is found.

gdb/doc/
	* gdb.texinfo (Create and Delete Tracepoints): Describe changed
	behavior of tracepoint.
	(General Query Packets): New feature InstallInTrace.
	(Remote Configuration): Document "set remote
	install-in-trace-packet".

gdb/gdbserver/
	* server.c (handle_query): Handle InstallInTrace for qSupported.
	* tracepoint.c (add_tracepoint): Sort list.
	(install_tracepoint, download_tracepoint): New.
	(cmd_qtdp): Call them to install and download tracepoints.
	(sort_tracepoints): Removed.
	(cmd_qtstart): Update.

gdb/testsuite/
	* gdb.trace/change-loc-1.c: New.
	* gdb.trace/change-loc-2.c: New.
	* gdb.trace/change-loc.c: New.
	* gdb.trace/change-loc.exp:  New.
	* gdb.trace/change-loc.h:  New.
	* gdb.trace/trace-break.c (marker): Define new symbol.
	* gdb.trace/trace-break.exp (break_trace_same_addr_5):
        New.
	(break_trace_same_addr_6): New.
This commit is contained in:
Yao Qi
2011-11-14 15:18:54 +00:00
parent 5c73ff4ec2
commit 1e4d17643d
20 changed files with 944 additions and 93 deletions

View File

@ -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);
}