Add fast tracepoints.

* arch-utils.h (default_fast_tracepoint_valid_at): Declare.
	* arch-utils.c (default_fast_tracepoint_valid_at): New function.
	* breakpoint.h (enum bptype): Add bp_fast_tracepoint.
	* breakpoint.c (tracepoint_type): New function.
	(ALL_TRACEPOINTS): Use it.
	(should_be_inserted): Ditto.
	(bpstat_check_location): Ditto.
	(print_one_breakpoint_location): Ditto.
	(user_settable_breakpoint): Ditto.
	(set_breakpoint_location_function): Ditto.
	(disable_breakpoints_in_shlibs): Ditto.
	(delete_trace_command): Ditto.
	(print_it_typical): Add bp_fast_tracepoint case.
	(bpstat_what): Ditto.
	(print_one_breakpoint_location): Ditto.
	(allocate_bp_location): Ditto.
	(mention): Ditto.
	(breakpoint_re_set_one): Ditto.
	(disable_command): Ditto.
	(enable_command): Ditto.
	(check_fast_tracepoint_sals): New function.
	(break_command_really): Call it.
	(ftrace_command): New function.
	(_initialize_breakpoint): Add ftrace command.
	* gdbarch.sh (fast_tracepoint_valid_at): New.
	* gdbarch.h, gdbarch.c: Regenerate.
	* i386-tdep.c (i386_fast_tracepoint_valid_at): New function.
	(i386_gdbarch_init): Use it.
	* remote.c (struct remote_state): New field fast_tracepoints.
	(PACKET_FastTracepoints): New packet config type.
	(remote_fast_tracepoint_feature): New function.
	(remote_protocol_features): Add FastTracepoints.
	(remote_supports_fast_tracepoints): New function.
	(_initialize_remote): Add FastTracepoints.
	* tracepoint.c (download_tracepoint): Add fast tracepoint option.
	* NEWS: Mention fast tracepoints.

	* gdb.texinfo (Create and Delete Tracepoints): Describe fast
	tracepoints.
	(Tracepoint Packets): Describe remote protocol for fast
	tracepoints.

	* gdb.trace/tracecmd.exp: Test ftrace.
This commit is contained in:
Stan Shebs 2010-01-06 04:20:27 +00:00
parent 737a160ed9
commit 7a697b8dd7
16 changed files with 353 additions and 19 deletions

View File

@ -1,3 +1,43 @@
2010-01-05 Stan Shebs <stan@codesourcery.com>
Add fast tracepoints.
* arch-utils.h (default_fast_tracepoint_valid_at): Declare.
* arch-utils.c (default_fast_tracepoint_valid_at): New function.
* breakpoint.h (enum bptype): Add bp_fast_tracepoint.
* breakpoint.c (tracepoint_type): New function.
(ALL_TRACEPOINTS): Use it.
(should_be_inserted): Ditto.
(bpstat_check_location): Ditto.
(print_one_breakpoint_location): Ditto.
(user_settable_breakpoint): Ditto.
(set_breakpoint_location_function): Ditto.
(disable_breakpoints_in_shlibs): Ditto.
(delete_trace_command): Ditto.
(print_it_typical): Add bp_fast_tracepoint case.
(bpstat_what): Ditto.
(print_one_breakpoint_location): Ditto.
(allocate_bp_location): Ditto.
(mention): Ditto.
(breakpoint_re_set_one): Ditto.
(disable_command): Ditto.
(enable_command): Ditto.
(check_fast_tracepoint_sals): New function.
(break_command_really): Call it.
(ftrace_command): New function.
(_initialize_breakpoint): Add ftrace command.
* gdbarch.sh (fast_tracepoint_valid_at): New.
* gdbarch.h, gdbarch.c: Regenerate.
* i386-tdep.c (i386_fast_tracepoint_valid_at): New function.
(i386_gdbarch_init): Use it.
* remote.c (struct remote_state): New field fast_tracepoints.
(PACKET_FastTracepoints): New packet config type.
(remote_fast_tracepoint_feature): New function.
(remote_protocol_features): Add FastTracepoints.
(remote_supports_fast_tracepoints): New function.
(_initialize_remote): Add FastTracepoints.
* tracepoint.c (download_tracepoint): Add fast tracepoint option.
* NEWS: Mention fast tracepoints.
2010-01-06 Joel Brobecker <brobecker@adacore.com>
* gdb-gdb.py: New file.

View File

@ -36,7 +36,19 @@ Renesas RX rx
tracepoint actions and condition expressions. Use the "tvariable"
command to create, and "info tvariables" to view; see "Trace State
Variables" in the manual for more detail.
* Fast tracepoints
GDB now includes an option for defining fast tracepoints, which
targets may implement more efficiently, such as by installing a jump
into the target agent rather than a trap instruction. The resulting
speedup can be by two orders of magnitude or more, although the
tradeoff is that some program locations on some target architectures
might not allow fast tracepoint installation, for instance if the
instruction to be replaced is shorter than the jump. To request a
fast tracepoint, use the "ftrace" command, with syntax identical to
the regular trace command.
* Changed commands
disassemble
@ -101,6 +113,9 @@ teval EXPR, ...
Evaluate the given expressions without collecting anything into the
trace buffer. (Valid in tracepoint actions only.)
ftrace FN / FILE:LINE / *ADDR
Define a fast tracepoint at the given function, line, or address.
* New options
set follow-exec-mode new|same

View File

@ -765,6 +765,17 @@ default_has_shared_address_space (struct gdbarch *gdbarch)
return 0;
}
int
default_fast_tracepoint_valid_at (struct gdbarch *gdbarch,
CORE_ADDR addr, int *isize, char **msg)
{
/* We don't know if maybe the target has some way to do fast
tracepoints that doesn't need gdbarch, so always say yes. */
if (msg)
*msg = NULL;
return 1;
}
/* */
extern initialize_file_ftype _initialize_gdbarch_utils; /* -Wmissing-prototypes */

View File

@ -155,4 +155,8 @@ extern struct gdbarch *get_current_arch (void);
extern int default_has_shared_address_space (struct gdbarch *);
extern int default_fast_tracepoint_valid_at (struct gdbarch *gdbarch,
CORE_ADDR addr,
int *isize, char **msg);
#endif

View File

@ -353,7 +353,7 @@ static int overlay_events_enabled;
#define ALL_TRACEPOINTS(B) \
for (B = breakpoint_chain; B; B = B->next) \
if ((B)->type == bp_tracepoint)
if (tracepoint_type (B))
/* Chains of all breakpoints defined. */
@ -422,6 +422,14 @@ clear_breakpoint_hit_counts (void)
b->hit_count = 0;
}
/* Encapsulate tests for different types of tracepoints. */
static int
tracepoint_type (const struct breakpoint *b)
{
return (b->type == bp_tracepoint || b->type == bp_fast_tracepoint);
}
/* Default address, symtab and line to put a breakpoint at
for "break" command with no arg.
if default_breakpoint_valid is zero, the other three are
@ -1282,7 +1290,7 @@ should_be_inserted (struct bp_location *bpt)
/* Tracepoints are inserted by the target at a time of its choosing,
not by us. */
if (bpt->owner->type == bp_tracepoint)
if (tracepoint_type (bpt->owner))
return 0;
return 1;
@ -2977,6 +2985,7 @@ print_it_typical (bpstat bs)
case bp_watchpoint_scope:
case bp_call_dummy:
case bp_tracepoint:
case bp_fast_tracepoint:
case bp_jit_event:
default:
result = PRINT_UNKNOWN;
@ -3322,7 +3331,7 @@ bpstat_check_location (const struct bp_location *bl,
/* By definition, the inferior does not report stops at
tracepoints. */
if (b->type == bp_tracepoint)
if (tracepoint_type (b))
return 0;
if (b->type != bp_watchpoint
@ -3914,11 +3923,12 @@ bpstat_what (bpstat bs)
retval.call_dummy = 1;
break;
case bp_tracepoint:
case bp_fast_tracepoint:
/* Tracepoint hits should not be reported back to GDB, and
if one got through somehow, it should have been filtered
out already. */
internal_error (__FILE__, __LINE__,
_("bpstat_what: bp_tracepoint encountered"));
_("bpstat_what: tracepoint encountered"));
break;
}
current_action = table[(int) bs_class][(int) current_action];
@ -4044,6 +4054,7 @@ print_one_breakpoint_location (struct breakpoint *b,
{bp_longjmp_master, "longjmp master"},
{bp_catchpoint, "catchpoint"},
{bp_tracepoint, "tracepoint"},
{bp_fast_tracepoint, "fast tracepoint"},
{bp_jit_event, "jit events"},
};
@ -4173,6 +4184,7 @@ print_one_breakpoint_location (struct breakpoint *b,
case bp_overlay_event:
case bp_longjmp_master:
case bp_tracepoint:
case bp_fast_tracepoint:
case bp_jit_event:
if (opts.addressprint)
{
@ -4258,7 +4270,7 @@ print_one_breakpoint_location (struct breakpoint *b,
because the condition is an internal implementation detail
that we do not want to expose to the user. */
annotate_field (7);
if (b->type == bp_tracepoint)
if (tracepoint_type (b))
ui_out_text (uiout, "\ttrace only if ");
else
ui_out_text (uiout, "\tstop only if ");
@ -4451,7 +4463,7 @@ user_settable_breakpoint (const struct breakpoint *b)
return (b->type == bp_breakpoint
|| b->type == bp_catchpoint
|| b->type == bp_hardware_breakpoint
|| b->type == bp_tracepoint
|| tracepoint_type (b)
|| b->type == bp_watchpoint
|| b->type == bp_read_watchpoint
|| b->type == bp_access_watchpoint
@ -4804,6 +4816,7 @@ allocate_bp_location (struct breakpoint *bpt)
{
case bp_breakpoint:
case bp_tracepoint:
case bp_fast_tracepoint:
case bp_until:
case bp_finish:
case bp_longjmp:
@ -4900,7 +4913,7 @@ set_breakpoint_location_function (struct bp_location *loc)
{
if (loc->owner->type == bp_breakpoint
|| loc->owner->type == bp_hardware_breakpoint
|| loc->owner->type == bp_tracepoint)
|| tracepoint_type (loc->owner))
{
find_pc_partial_function (loc->address, &(loc->function_name),
NULL, NULL);
@ -5159,7 +5172,7 @@ disable_breakpoints_in_shlibs (void)
to insert those breakpoints and fail. */
if (((b->type == bp_breakpoint)
|| (b->type == bp_hardware_breakpoint)
|| (b->type == bp_tracepoint))
|| (tracepoint_type (b)))
&& loc->pspace == current_program_space
&& !loc->shlib_disabled
#ifdef PC_SOLIB
@ -6091,6 +6104,16 @@ mention (struct breakpoint *b)
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_until:
case bp_finish:
@ -6593,6 +6616,38 @@ breakpoint_sals_to_pc (struct symtabs_and_lines *sals,
resolve_sal_pc (&sals->sals[i]);
}
/* Fast tracepoints may have restrictions on valid locations. For
instance, a fast tracepoint using a jump instead of a trap will
likely have to overwrite more bytes than a trap would, and so can
only be placed where the instruction is longer than the jump, or a
multi-instruction sequence does not have a jump into the middle of
it, etc. */
static void
check_fast_tracepoint_sals (struct gdbarch *gdbarch,
struct symtabs_and_lines *sals)
{
int i, rslt;
struct symtab_and_line *sal;
char *msg;
struct cleanup *old_chain;
for (i = 0; i < sals->nelts; i++)
{
sal = &sals->sals[i];
rslt = gdbarch_fast_tracepoint_valid_at (gdbarch, sal->pc,
NULL, &msg);
old_chain = make_cleanup (xfree, msg);
if (!rslt)
error (_("May not have a fast tracepoint at 0x%s%s"),
paddress (gdbarch, sal->pc), (msg ? msg : ""));
do_cleanups (old_chain);
}
}
static void
do_captured_parse_breakpoint (struct ui_out *ui, void *data)
{
@ -6794,9 +6849,13 @@ break_command_really (struct gdbarch *gdbarch,
breakpoint_sals_to_pc (&sals, addr_start);
type_wanted = (traceflag
? bp_tracepoint
? (hardwareflag ? bp_fast_tracepoint : bp_tracepoint)
: (hardwareflag ? bp_hardware_breakpoint : bp_breakpoint));
/* Fast tracepoints may have additional restrictions on location. */
if (type_wanted == bp_fast_tracepoint)
check_fast_tracepoint_sals (gdbarch, &sals);
/* Verify that condition can be parsed, before setting any
breakpoints. Allocate a separate condition expression for each
breakpoint. */
@ -8970,6 +9029,7 @@ breakpoint_re_set_one (void *bint)
case bp_breakpoint:
case bp_hardware_breakpoint:
case bp_tracepoint:
case bp_fast_tracepoint:
/* Do not attempt to re-set breakpoints disabled during startup. */
if (b->enable_state == bp_startup_disabled)
return 0;
@ -9369,6 +9429,7 @@ disable_command (char *args, int from_tty)
continue;
case bp_breakpoint:
case bp_tracepoint:
case bp_fast_tracepoint:
case bp_catchpoint:
case bp_hardware_breakpoint:
case bp_watchpoint:
@ -9462,6 +9523,7 @@ enable_command (char *args, int from_tty)
continue;
case bp_breakpoint:
case bp_tracepoint:
case bp_fast_tracepoint:
case bp_catchpoint:
case bp_hardware_breakpoint:
case bp_watchpoint:
@ -9769,6 +9831,22 @@ trace_command (char *arg, int from_tty)
set_tracepoint_count (breakpoint_count);
}
void
ftrace_command (char *arg, int from_tty)
{
break_command_really (get_current_arch (),
arg,
NULL, 0, 1 /* parse arg */,
0 /* tempflag */, 1 /* hardwareflag */,
1 /* traceflag */,
0 /* Ignore count */,
pending_break_support,
NULL,
from_tty,
1 /* enabled */);
set_tracepoint_count (breakpoint_count);
}
/* Print information on tracepoint number TPNUM_EXP, or all if
omitted. */
@ -9846,7 +9924,7 @@ delete_trace_command (char *arg, int from_tty)
{
ALL_BREAKPOINTS_SAFE (b, temp)
{
if (b->type == bp_tracepoint
if (tracepoint_type (b)
&& b->number >= 0)
delete_breakpoint (b);
}
@ -10501,6 +10579,13 @@ Do \"help tracepoints\" for info on other tracepoint commands."));
add_com_alias ("tra", "trace", class_alias, 1);
add_com_alias ("trac", "trace", class_alias, 1);
c = add_com ("ftrace", class_breakpoint, ftrace_command, _("\
Set a fast tracepoint at specified line or function.\n\
\n"
BREAK_ARGS_HELP ("ftrace") "\n\
Do \"help tracepoints\" for info on other tracepoint commands."));
set_cmd_completer (c, location_completer);
add_info ("tracepoints", tracepoints_info, _("\
Status of tracepoints, or tracepoint number NUMBER.\n\
Convenience variable \"$tpnum\" contains the number of the\n\

View File

@ -121,6 +121,7 @@ enum bptype
bp_catchpoint,
bp_tracepoint,
bp_fast_tracepoint,
/* Event for JIT compiled code generation or deletion. */
bp_jit_event,

View File

@ -1,3 +1,10 @@
2010-01-05 Stan Shebs <stan@codesourcery.com>
* gdb.texinfo (Create and Delete Tracepoints): Describe fast
tracepoints.
(Tracepoint Packets): Describe remote protocol for fast
tracepoints.
2010-01-01 Joel Brobecker <brobecker@adacore.com>
Update the "Start of New Year Procedure".

View File

@ -9323,6 +9323,11 @@ expressions and ignore counts on tracepoints have no effect, and
tracepoints cannot run @value{GDBN} commands when they are
hit. Tracepoints may not be thread-specific either.
@cindex fast tracepoints
Some targets may support @dfn{fast tracepoints}, which are inserted in
a different way (such as with a jump instead of a trap), that is
faster but possibly restricted in where they may be installed.
This section describes commands to set tracepoints and associated
conditions and actions.
@ -9378,6 +9383,20 @@ if the value is nonzero---that is, if @var{cond} evaluates as true.
@xref{Tracepoint Conditions, ,Tracepoint Conditions}, for more
information on tracepoint conditions.
@item ftrace @var{location} [ if @var{cond} ]
@cindex set fast tracepoint
@kindex ftrace
The @code{ftrace} command sets a fast tracepoint. For targets that
support them, fast tracepoints will use a more efficient but possibly
less general technique to trigger data collection, such as a jump
instruction instead of a trap, or some sort of hardware support. It
may not be possible to create a fast tracepoint at the desired
location, in which case the command will exit with an explanatory
message.
@value{GDBN} handles arguments to @code{ftrace} exactly as for
@code{trace}.
@vindex $tpnum
@cindex last tracepoint number
@cindex recent tracepoint number
@ -29975,16 +29994,19 @@ tracepoints (@pxref{Tracepoints}).
@table @samp
@item QTDP:@var{n}:@var{addr}:@var{ena}:@var{step}:@var{pass}[:X@var{len},@var{bytes}]@r{[}-@r{]}
@item QTDP:@var{n}:@var{addr}:@var{ena}:@var{step}:@var{pass}[:F@var{flen}][:X@var{len},@var{bytes}]@r{[}-@r{]}
Create a new tracepoint, number @var{n}, at @var{addr}. If @var{ena}
is @samp{E}, then the tracepoint is enabled; if it is @samp{D}, then
the tracepoint is disabled. @var{step} is the tracepoint's step
count, and @var{pass} is its pass count. If an @samp{X} is present,
it introduces a tracepoint condition, which consists of a hexadecimal
length, followed by a comma and hex-encoded bytes, in a manner similar
to action encodings as described below. If the trailing @samp{-} is
present, further @samp{QTDP} packets will follow to specify this
tracepoint's actions.
count, and @var{pass} is its pass count. If an @samp{F} is present,
then the tracepoint is to be a fast tracepoint, and the @var{flen} is
the number of bytes that the target should copy elsewhere to make room
for the tracepoint. If an @samp{X} is present, it introduces a
tracepoint condition, which consists of a hexadecimal length, followed
by a comma and hex-encoded bytes, in a manner similar to action
encodings as described below. If the trailing @samp{-} is present,
further @samp{QTDP} packets will follow to specify this tracepoint's
actions.
Replies:
@table @samp

View File

@ -250,6 +250,7 @@ struct gdbarch
int has_global_solist;
int has_global_breakpoints;
gdbarch_has_shared_address_space_ftype *has_shared_address_space;
gdbarch_fast_tracepoint_valid_at_ftype *fast_tracepoint_valid_at;
};
@ -391,6 +392,7 @@ struct gdbarch startup_gdbarch =
0, /* has_global_solist */
0, /* has_global_breakpoints */
default_has_shared_address_space, /* has_shared_address_space */
default_fast_tracepoint_valid_at, /* fast_tracepoint_valid_at */
/* startup_gdbarch() */
};
@ -475,6 +477,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
gdbarch->target_signal_from_host = default_target_signal_from_host;
gdbarch->target_signal_to_host = default_target_signal_to_host;
gdbarch->has_shared_address_space = default_has_shared_address_space;
gdbarch->fast_tracepoint_valid_at = default_fast_tracepoint_valid_at;
/* gdbarch_alloc() */
return gdbarch;
@ -653,6 +656,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of has_global_solist, invalid_p == 0 */
/* Skip verify of has_global_breakpoints, invalid_p == 0 */
/* Skip verify of has_shared_address_space, invalid_p == 0 */
/* Skip verify of fast_tracepoint_valid_at, invalid_p == 0 */
buf = ui_file_xstrdup (log, &length);
make_cleanup (xfree, buf);
if (length > 0)
@ -825,6 +829,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
fprintf_unfiltered (file,
"gdbarch_dump: elf_make_msymbol_special = <%s>\n",
host_address_to_string (gdbarch->elf_make_msymbol_special));
fprintf_unfiltered (file,
"gdbarch_dump: fast_tracepoint_valid_at = <%s>\n",
host_address_to_string (gdbarch->fast_tracepoint_valid_at));
fprintf_unfiltered (file,
"gdbarch_dump: gdbarch_fetch_pointer_argument_p() = %d\n",
gdbarch_fetch_pointer_argument_p (gdbarch));
@ -3528,6 +3535,23 @@ set_gdbarch_has_shared_address_space (struct gdbarch *gdbarch,
gdbarch->has_shared_address_space = has_shared_address_space;
}
int
gdbarch_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr, int *isize, char **msg)
{
gdb_assert (gdbarch != NULL);
gdb_assert (gdbarch->fast_tracepoint_valid_at != NULL);
if (gdbarch_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "gdbarch_fast_tracepoint_valid_at called\n");
return gdbarch->fast_tracepoint_valid_at (gdbarch, addr, isize, msg);
}
void
set_gdbarch_fast_tracepoint_valid_at (struct gdbarch *gdbarch,
gdbarch_fast_tracepoint_valid_at_ftype fast_tracepoint_valid_at)
{
gdbarch->fast_tracepoint_valid_at = fast_tracepoint_valid_at;
}
/* Keep a registry of per-architecture data-pointers required by GDB
modules. */

View File

@ -909,6 +909,12 @@ typedef int (gdbarch_has_shared_address_space_ftype) (struct gdbarch *gdbarch);
extern int gdbarch_has_shared_address_space (struct gdbarch *gdbarch);
extern void set_gdbarch_has_shared_address_space (struct gdbarch *gdbarch, gdbarch_has_shared_address_space_ftype *has_shared_address_space);
/* True if a fast tracepoint can be set at an address. */
typedef int (gdbarch_fast_tracepoint_valid_at_ftype) (struct gdbarch *gdbarch, CORE_ADDR addr, int *isize, char **msg);
extern int gdbarch_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr, int *isize, char **msg);
extern void set_gdbarch_fast_tracepoint_valid_at (struct gdbarch *gdbarch, gdbarch_fast_tracepoint_valid_at_ftype *fast_tracepoint_valid_at);
/* Definition for an unknown syscall, used basically in error-cases. */
#define UNKNOWN_SYSCALL (-1)

View File

@ -759,6 +759,9 @@ v:int:has_global_breakpoints:::0:0::0
# True if inferiors share an address space (e.g., uClinux).
m:int:has_shared_address_space:void:::default_has_shared_address_space::0
# True if a fast tracepoint can be set at an address.
m:int:fast_tracepoint_valid_at:CORE_ADDR addr, int *isize, char **msg:addr, isize, msg::default_fast_tracepoint_valid_at::0
EOF
}

View File

@ -43,6 +43,7 @@
#include "target.h"
#include "value.h"
#include "dis-asm.h"
#include "disasm.h"
#include "gdb_assert.h"
#include "gdb_string.h"
@ -5567,6 +5568,49 @@ static const int i386_record_regmap[] =
I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
};
/* Check that the given address appears suitable for a fast
tracepoint, which on x86 means that we need an instruction of at
least 5 bytes, so that we can overwrite it with a 4-byte-offset
jump and not have to worry about program jumps to an address in the
middle of the tracepoint jump. Returns 1 if OK, and writes a size
of instruction to replace, and 0 if not, plus an explanatory
string. */
static int
i386_fast_tracepoint_valid_at (struct gdbarch *gdbarch,
CORE_ADDR addr, int *isize, char **msg)
{
int len, jumplen;
static struct ui_file *gdb_null = NULL;
/* This is based on the target agent using a 4-byte relative jump.
Alternate future possibilities include 8-byte offset for x86-84,
or 3-byte jumps if the program has trampoline space close by. */
jumplen = 5;
/* Dummy file descriptor for the disassembler. */
if (!gdb_null)
gdb_null = ui_file_new ();
/* Check for fit. */
len = gdb_print_insn (gdbarch, addr, gdb_null, NULL);
if (len < jumplen)
{
/* Return a bit of target-specific detail to add to the caller's
generic failure message. */
if (msg)
*msg = xstrprintf (_("; instruction is only %d bytes long, need at least %d bytes for the jump"),
len, jumplen);
return 0;
}
if (isize)
*isize = len;
if (msg)
*msg = NULL;
return 1;
}
static struct gdbarch *
i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@ -5769,6 +5813,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_skip_permanent_breakpoint (gdbarch,
i386_skip_permanent_breakpoint);
set_gdbarch_fast_tracepoint_valid_at (gdbarch,
i386_fast_tracepoint_valid_at);
return gdbarch;
}

View File

@ -298,6 +298,9 @@ struct remote_state
/* True if the stub reports support for conditional tracepoints. */
int cond_tracepoints;
/* True if the stub reports support for fast tracepoints. */
int fast_tracepoints;
/* Nonzero if the user has pressed Ctrl-C, but the target hasn't
responded to that. */
int ctrlc_pending_p;
@ -1066,6 +1069,7 @@ enum {
PACKET_qXfer_siginfo_write,
PACKET_qAttached,
PACKET_ConditionalTracepoints,
PACKET_FastTracepoints,
PACKET_bc,
PACKET_bs,
PACKET_MAX
@ -3136,6 +3140,15 @@ remote_cond_tracepoint_feature (const struct protocol_feature *feature,
rs->cond_tracepoints = (support == PACKET_ENABLE);
}
static void
remote_fast_tracepoint_feature (const struct protocol_feature *feature,
enum packet_support support,
const char *value)
{
struct remote_state *rs = get_remote_state ();
rs->fast_tracepoints = (support == PACKET_ENABLE);
}
static struct protocol_feature remote_protocol_features[] = {
{ "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
{ "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet,
@ -3164,6 +3177,8 @@ static struct protocol_feature remote_protocol_features[] = {
PACKET_qXfer_siginfo_write },
{ "ConditionalTracepoints", PACKET_DISABLE, remote_cond_tracepoint_feature,
PACKET_ConditionalTracepoints },
{ "FastTracepoints", PACKET_DISABLE, remote_fast_tracepoint_feature,
PACKET_FastTracepoints },
{ "ReverseContinue", PACKET_DISABLE, remote_supported_packet,
PACKET_bc },
{ "ReverseStep", PACKET_DISABLE, remote_supported_packet,
@ -8895,6 +8910,13 @@ remote_supports_cond_tracepoints (void)
return rs->cond_tracepoints;
}
int
remote_supports_fast_tracepoints (void)
{
struct remote_state *rs = get_remote_state ();
return rs->fast_tracepoints;
}
static void
init_remote_ops (void)
{
@ -9371,6 +9393,8 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
add_packet_config_cmd (&remote_protocol_packets[PACKET_ConditionalTracepoints],
"ConditionalTracepoints", "conditional-tracepoints", 0);
add_packet_config_cmd (&remote_protocol_packets[PACKET_FastTracepoints],
"FastTracepoints", "fast-tracepoints", 0);
/* Keep the old ``set remote Z-packet ...'' working. Each individual
Z sub-packet has its own set and show commands, but users may

View File

@ -1,3 +1,7 @@
2010-01-05 Stan Shebs <stan@codesourcery.com>
* gdb.trace/tracecmd.exp: Test ftrace.
2010-01-04 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* gdb.xml/tdesc-regs.exp: Support s390*-*-* targets.

View File

@ -164,4 +164,16 @@ gdb_test "info trace" "in gdb_recursion_test.*$srcfile:$testline1.*trace only if
# 1.14 help trace
gdb_test "help trace" "Set a tracepoint at .*" "1.14: help trace"
# 1.15 ftrace
gdb_delete_tracepoints
send_gdb "ftrace gdb_recursion_test\n"
# Acceptance vs rejection of a location are target-specific, so allow both.
gdb_expect {
-re "Fast tracepoint $decimal at $hex: file.*$srcfile, line $testline1.*$gdb_prompt $"
{ pass "Set a fast tracepoint" }
-re ".*May not have a fast tracepoint at $hex.*$gdb_prompt $"
{ pass "Declined to set a fast tracepoint" }
timeout { fail "Timeout while setting fast tracepoint" }
}

View File

@ -34,6 +34,7 @@
#include "tracepoint.h"
#include "remote.h"
extern int remote_supports_cond_tracepoints (void);
extern int remote_supports_fast_tracepoints (void);
extern char *unpack_varlen_hex (char *buff, ULONGEST *result);
#include "linespec.h"
#include "regcache.h"
@ -1690,6 +1691,7 @@ trace_start_command (char *args, int from_tty)
void
download_tracepoint (struct breakpoint *t)
{
CORE_ADDR tpaddr;
char tmp[40];
char buf[2048];
char **tdp_actions;
@ -1699,11 +1701,38 @@ download_tracepoint (struct breakpoint *t)
struct agent_expr *aexpr;
struct cleanup *aexpr_chain = NULL;
sprintf_vma (tmp, (t->loc ? t->loc->address : 0));
tpaddr = t->loc->address;
sprintf_vma (tmp, (t->loc ? tpaddr : 0));
sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number,
tmp, /* address */
(t->enable_state == bp_enabled ? 'E' : 'D'),
t->step_count, t->pass_count);
/* Fast tracepoints are mostly handled by the target, but we can
tell the target how big of an instruction block should be moved
around. */
if (t->type == bp_fast_tracepoint)
{
/* Only test for support at download time; we may not know
target capabilities at definition time. */
if (remote_supports_fast_tracepoints ())
{
int isize;
if (gdbarch_fast_tracepoint_valid_at (get_current_arch (),
tpaddr, &isize, NULL))
sprintf (buf + strlen (buf), ":F%x", isize);
else
/* If it passed validation at definition but fails now,
something is very wrong. */
internal_error (__FILE__, __LINE__,
"Fast tracepoint not valid during download");
}
else
/* Fast tracepoints are functionally identical to regular
tracepoints, so don't take lack of support as a reason to
give up on the trace run. */
warning (_("Target does not support fast tracepoints, downloading %d as regular tracepoint"), t->number);
}
/* If the tracepoint has a conditional, make it into an agent
expression and append to the definition. */
if (t->loc->cond)