mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
record btrace: add configuration struct
Add a struct to describe the branch trace configuration and use it for enabling branch tracing. The user will be able to set configuration fields for each tracing format to be used for new threads. The actual configuration that is active for a given thread will be shown in the "info record" command. At the moment, the configuration struct only contains a format field that is set to the only available format. The format is the only configuration option that can not be set via set commands. It is given as argument to the "record btrace" command when starting recording. 2015-02-09 Markus Metzger <markus.t.metzger@intel.com> * Makefile.in (XMLFILES): Add btrace-conf.dtd. * x86-linux-nat.c (x86_linux_enable_btrace): Update parameters. (x86_linux_btrace_conf): New. (x86_linux_create_target): Initialize to_btrace_conf. * nat/linux-btrace.c (linux_enable_btrace): Update parameters. Check format. Split into this and ... (linux_enable_bts): ... this. (linux_btrace_conf): New. (perf_event_skip_record): Renamed into ... (perf_event_skip_bts_record): ... this. Updated users. (linux_disable_btrace): Split into this and ... (linux_disable_bts): ... this. (linux_read_btrace): Check format. * nat/linux-btrace.h (linux_enable_btrace): Update parameters. (linux_btrace_conf): New. (btrace_target_info)<ptid>: Moved. (btrace_target_info)<conf>: New. (btrace_target_info): Split into this and ... (btrace_tinfo_bts): ... this. Updated users. * btrace.c (btrace_enable): Update parameters. (btrace_conf, parse_xml_btrace_conf_bts, parse_xml_btrace_conf) (btrace_conf_children, btrace_conf_attributes) (btrace_conf_elements): New. * btrace.h (btrace_enable): Update parameters. (btrace_conf, parse_xml_btrace_conf): New. * common/btrace-common.h (btrace_config): New. * feature/btrace-conf.dtd: New. * record-btrace.c (record_btrace_conf): New. (record_btrace_cmdlist): New. (record_btrace_enable_warn, record_btrace_open): Pass &record_btrace_conf. (record_btrace_info): Print recording format. (cmd_record_btrace_bts_start): New. (cmd_record_btrace_start): Call cmd_record_btrace_bts_start. (_initialize_record_btrace): Add "record btrace bts" subcommand. Add "record bts" alias command. * remote.c (remote_state)<btrace_config>: New. (remote_btrace_reset, PACKET_qXfer_btrace_conf): New. (remote_protocol_features): Add qXfer:btrace-conf:read. (remote_open_1): Call remote_btrace_reset. (remote_xfer_partial): Handle TARGET_OBJECT_BTRACE_CONF. (btrace_target_info)<conf>: New. (btrace_sync_conf, btrace_read_config): New. (remote_enable_btrace): Update parameters. Call btrace_sync_conf and btrace_read_conf. (remote_btrace_conf): New. (init_remote_ops): Initialize to_btrace_conf. (_initialize_remote): Add qXfer:btrace-conf packet. * target.c (target_enable_btrace): Update parameters. (target_btrace_conf): New. * target.h (target_enable_btrace): Update parameters. (target_btrace_conf): New. (target_object)<TARGET_OBJECT_BTRACE_CONF>: New. (target_ops)<to_enable_btrace>: Update parameters and comment. (target_ops)<to_btrace_conf>: New. * target-delegates: Regenerate. * target-debug.h (target_debug_print_const_struct_btrace_config_p) (target_debug_print_const_struct_btrace_target_info_p): New. NEWS: Announce new command and new packet. doc/ * gdb.texinfo (Process Record and Replay): Describe the "record btrace bts" command. (General Query Packets): Describe qXfer:btrace-conf:read packet. (Branch Trace Configuration Format): New. gdbserver/ * linux-low.c (linux_low_enable_btrace): Update parameters. (linux_low_btrace_conf): New. (linux_target_ops)<to_btrace_conf>: Initialize. * server.c (current_btrace_conf): New. (handle_btrace_enable): Rename to ... (handle_btrace_enable_bts): ... this. Pass ¤t_btrace_conf to target_enable_btrace. Update comment. Update users. (handle_qxfer_btrace_conf): New. (qxfer_packets): Add btrace-conf entry. (handle_query): Report qXfer:btrace-conf:read as supported packet. * target.h (target_ops)<enable_btrace>: Update parameters and comment. (target_ops)<read_btrace_conf>: New. (target_enable_btrace): Update parameters. (target_read_btrace_conf): New. testsuite/ * gdb.btrace/delta.exp: Update "info record" output. * gdb.btrace/enable.exp: Update "info record" output. * gdb.btrace/finish.exp: Update "info record" output. * gdb.btrace/instruction_history.exp: Update "info record" output. * gdb.btrace/next.exp: Update "info record" output. * gdb.btrace/nexti.exp: Update "info record" output. * gdb.btrace/step.exp: Update "info record" output. * gdb.btrace/stepi.exp: Update "info record" output. * gdb.btrace/nohist.exp: Update "info record" output.
This commit is contained in:
parent
aadf7753fd
commit
f4abbc1682
@ -1,3 +1,65 @@
|
||||
2015-02-09 Markus Metzger <markus.t.metzger@intel.com>
|
||||
|
||||
* Makefile.in (XMLFILES): Add btrace-conf.dtd.
|
||||
* x86-linux-nat.c (x86_linux_enable_btrace): Update parameters.
|
||||
(x86_linux_btrace_conf): New.
|
||||
(x86_linux_create_target): Initialize to_btrace_conf.
|
||||
* nat/linux-btrace.c (linux_enable_btrace): Update parameters.
|
||||
Check format. Split into this and ...
|
||||
(linux_enable_bts): ... this.
|
||||
(linux_btrace_conf): New.
|
||||
(perf_event_skip_record): Renamed into ...
|
||||
(perf_event_skip_bts_record): ... this. Updated users.
|
||||
(linux_disable_btrace): Split into this and ...
|
||||
(linux_disable_bts): ... this.
|
||||
(linux_read_btrace): Check format.
|
||||
* nat/linux-btrace.h (linux_enable_btrace): Update parameters.
|
||||
(linux_btrace_conf): New.
|
||||
(btrace_target_info)<ptid>: Moved.
|
||||
(btrace_target_info)<conf>: New.
|
||||
(btrace_target_info): Split into this and ...
|
||||
(btrace_tinfo_bts): ... this. Updated users.
|
||||
* btrace.c (btrace_enable): Update parameters.
|
||||
(btrace_conf, parse_xml_btrace_conf_bts, parse_xml_btrace_conf)
|
||||
(btrace_conf_children, btrace_conf_attributes)
|
||||
(btrace_conf_elements): New.
|
||||
* btrace.h (btrace_enable): Update parameters.
|
||||
(btrace_conf, parse_xml_btrace_conf): New.
|
||||
* common/btrace-common.h (btrace_config): New.
|
||||
* feature/btrace-conf.dtd: New.
|
||||
* record-btrace.c (record_btrace_conf): New.
|
||||
(record_btrace_cmdlist): New.
|
||||
(record_btrace_enable_warn, record_btrace_open): Pass
|
||||
&record_btrace_conf.
|
||||
(record_btrace_info): Print recording format.
|
||||
(cmd_record_btrace_bts_start): New.
|
||||
(cmd_record_btrace_start): Call cmd_record_btrace_bts_start.
|
||||
(_initialize_record_btrace): Add "record btrace bts" subcommand.
|
||||
Add "record bts" alias command.
|
||||
* remote.c (remote_state)<btrace_config>: New.
|
||||
(remote_btrace_reset, PACKET_qXfer_btrace_conf): New.
|
||||
(remote_protocol_features): Add qXfer:btrace-conf:read.
|
||||
(remote_open_1): Call remote_btrace_reset.
|
||||
(remote_xfer_partial): Handle TARGET_OBJECT_BTRACE_CONF.
|
||||
(btrace_target_info)<conf>: New.
|
||||
(btrace_sync_conf, btrace_read_config): New.
|
||||
(remote_enable_btrace): Update parameters. Call btrace_sync_conf and
|
||||
btrace_read_conf.
|
||||
(remote_btrace_conf): New.
|
||||
(init_remote_ops): Initialize to_btrace_conf.
|
||||
(_initialize_remote): Add qXfer:btrace-conf packet.
|
||||
* target.c (target_enable_btrace): Update parameters.
|
||||
(target_btrace_conf): New.
|
||||
* target.h (target_enable_btrace): Update parameters.
|
||||
(target_btrace_conf): New.
|
||||
(target_object)<TARGET_OBJECT_BTRACE_CONF>: New.
|
||||
(target_ops)<to_enable_btrace>: Update parameters and comment.
|
||||
(target_ops)<to_btrace_conf>: New.
|
||||
* target-delegates: Regenerate.
|
||||
* target-debug.h (target_debug_print_const_struct_btrace_config_p)
|
||||
(target_debug_print_const_struct_btrace_target_info_p): New.
|
||||
* NEWS: Announce new command and new packet.
|
||||
|
||||
2015-02-09 Markus Metzger <markus.t.metzger@intel.com>
|
||||
|
||||
* nat/linux-btrace.h (perf_event_buffer): New.
|
||||
|
@ -601,7 +601,7 @@ XMLFILES = $(srcdir)/features/gdb-target.dtd $(srcdir)/features/xinclude.dtd \
|
||||
$(srcdir)/features/library-list-aix.dtd \
|
||||
$(srcdir)/features/library-list-svr4.dtd $(srcdir)/features/osdata.dtd \
|
||||
$(srcdir)/features/threads.dtd $(srcdir)/features/traceframe-info.dtd \
|
||||
$(srcdir)/features/btrace.dtd
|
||||
$(srcdir)/features/btrace.dtd $(srcdir)/features/btrace-conf.dtd
|
||||
|
||||
# This is ser-unix.o for any system which supports a v7/BSD/SYSV/POSIX
|
||||
# interface to the serial port. Hopefully if get ported to OS/2, VMS,
|
||||
|
9
gdb/NEWS
9
gdb/NEWS
@ -24,6 +24,10 @@ maint print symbol-cache-statistics
|
||||
maint flush-symbol-cache
|
||||
Flush the contents of the symbol cache.
|
||||
|
||||
record btrace bts
|
||||
record bts
|
||||
Start branch trace recording using Branch Trace Store (BTS) format.
|
||||
|
||||
* New options
|
||||
|
||||
set max-completions
|
||||
@ -45,6 +49,11 @@ maint show symbol-cache-size
|
||||
** GDB now supports auto-loading of Python/Guile scripts contained in the
|
||||
special section named `.debug_gdb_scripts'.
|
||||
|
||||
* New remote packets
|
||||
|
||||
qXfer:btrace-conf:read
|
||||
Return the branch trace configuration for the current thread.
|
||||
|
||||
*** Changes in GDB 7.9
|
||||
|
||||
* GDB now supports hardware watchpoints on x86 GNU Hurd.
|
||||
|
71
gdb/btrace.c
71
gdb/btrace.c
@ -726,17 +726,17 @@ btrace_add_pc (struct thread_info *tp)
|
||||
/* See btrace.h. */
|
||||
|
||||
void
|
||||
btrace_enable (struct thread_info *tp)
|
||||
btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
|
||||
{
|
||||
if (tp->btrace.target != NULL)
|
||||
return;
|
||||
|
||||
if (!target_supports_btrace (BTRACE_FORMAT_BTS))
|
||||
if (!target_supports_btrace (conf->format))
|
||||
error (_("Target does not support branch tracing."));
|
||||
|
||||
DEBUG ("enable thread %d (%s)", tp->num, target_pid_to_str (tp->ptid));
|
||||
|
||||
tp->btrace.target = target_enable_btrace (tp->ptid);
|
||||
tp->btrace.target = target_enable_btrace (tp->ptid, conf);
|
||||
|
||||
/* Add an entry for the current PC so we start tracing from where we
|
||||
enabled it. */
|
||||
@ -746,6 +746,17 @@ btrace_enable (struct thread_info *tp)
|
||||
|
||||
/* See btrace.h. */
|
||||
|
||||
const struct btrace_config *
|
||||
btrace_conf (const struct btrace_thread_info *btinfo)
|
||||
{
|
||||
if (btinfo->target == NULL)
|
||||
return NULL;
|
||||
|
||||
return target_btrace_conf (btinfo->target);
|
||||
}
|
||||
|
||||
/* See btrace.h. */
|
||||
|
||||
void
|
||||
btrace_disable (struct thread_info *tp)
|
||||
{
|
||||
@ -1106,6 +1117,60 @@ parse_xml_btrace (struct btrace_data *btrace, const char *buffer)
|
||||
#endif /* !defined (HAVE_LIBEXPAT) */
|
||||
}
|
||||
|
||||
#if defined (HAVE_LIBEXPAT)
|
||||
|
||||
/* Parse a btrace-conf "bts" xml record. */
|
||||
|
||||
static void
|
||||
parse_xml_btrace_conf_bts (struct gdb_xml_parser *parser,
|
||||
const struct gdb_xml_element *element,
|
||||
void *user_data, VEC (gdb_xml_value_s) *attributes)
|
||||
{
|
||||
struct btrace_config *conf;
|
||||
|
||||
conf = user_data;
|
||||
conf->format = BTRACE_FORMAT_BTS;
|
||||
}
|
||||
|
||||
static const struct gdb_xml_element btrace_conf_children[] = {
|
||||
{ "bts", NULL, NULL, GDB_XML_EF_OPTIONAL, parse_xml_btrace_conf_bts, NULL },
|
||||
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct gdb_xml_attribute btrace_conf_attributes[] = {
|
||||
{ "version", GDB_XML_AF_NONE, NULL, NULL },
|
||||
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct gdb_xml_element btrace_conf_elements[] = {
|
||||
{ "btrace-conf", btrace_conf_attributes, btrace_conf_children,
|
||||
GDB_XML_EF_NONE, NULL, NULL },
|
||||
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
|
||||
};
|
||||
|
||||
#endif /* defined (HAVE_LIBEXPAT) */
|
||||
|
||||
/* See btrace.h. */
|
||||
|
||||
void
|
||||
parse_xml_btrace_conf (struct btrace_config *conf, const char *xml)
|
||||
{
|
||||
int errcode;
|
||||
|
||||
#if defined (HAVE_LIBEXPAT)
|
||||
|
||||
errcode = gdb_xml_parse_quick (_("btrace-conf"), "btrace-conf.dtd",
|
||||
btrace_conf_elements, xml, conf);
|
||||
if (errcode != 0)
|
||||
error (_("Error parsing branch trace configuration."));
|
||||
|
||||
#else /* !defined (HAVE_LIBEXPAT) */
|
||||
|
||||
error (_("XML parsing is not supported."));
|
||||
|
||||
#endif /* !defined (HAVE_LIBEXPAT) */
|
||||
}
|
||||
|
||||
/* See btrace.h. */
|
||||
|
||||
const struct btrace_insn *
|
||||
|
11
gdb/btrace.h
11
gdb/btrace.h
@ -215,7 +215,13 @@ struct btrace_thread_info
|
||||
};
|
||||
|
||||
/* Enable branch tracing for a thread. */
|
||||
extern void btrace_enable (struct thread_info *tp);
|
||||
extern void btrace_enable (struct thread_info *tp,
|
||||
const struct btrace_config *conf);
|
||||
|
||||
/* Get the branch trace configuration for a thread.
|
||||
Return NULL if branch tracing is not enabled for that thread. */
|
||||
extern const struct btrace_config *
|
||||
btrace_conf (const struct btrace_thread_info *);
|
||||
|
||||
/* Disable branch tracing for a thread.
|
||||
This will also delete the current branch trace data. */
|
||||
@ -238,6 +244,9 @@ extern void btrace_free_objfile (struct objfile *);
|
||||
/* Parse a branch trace xml document XML into DATA. */
|
||||
extern void parse_xml_btrace (struct btrace_data *data, const char *xml);
|
||||
|
||||
/* Parse a branch trace configuration xml document XML into CONF. */
|
||||
extern void parse_xml_btrace_conf (struct btrace_config *conf, const char *xml);
|
||||
|
||||
/* Dereference a branch trace instruction iterator. Return a pointer to the
|
||||
instruction the iterator points to. */
|
||||
extern const struct btrace_insn *
|
||||
|
@ -61,6 +61,17 @@ enum btrace_format
|
||||
BTRACE_FORMAT_BTS
|
||||
};
|
||||
|
||||
/* A branch tracing configuration.
|
||||
|
||||
This describes the requested configuration as well as the actually
|
||||
obtained configuration. */
|
||||
|
||||
struct btrace_config
|
||||
{
|
||||
/* The branch tracing format. */
|
||||
enum btrace_format format;
|
||||
};
|
||||
|
||||
/* Branch trace in BTS format. */
|
||||
struct btrace_data_bts
|
||||
{
|
||||
|
@ -1,3 +1,10 @@
|
||||
2015-02-09 Markus Metzger <markus.t.metzger@intel.com>
|
||||
|
||||
* gdb.texinfo (Process Record and Replay): Describe the "record
|
||||
btrace bts" command.
|
||||
(General Query Packets): Describe qXfer:btrace-conf:read packet.
|
||||
(Branch Trace Configuration Format): New.
|
||||
|
||||
2015-01-31 Gary Benson <gbenson@redhat.com>
|
||||
Doug Evans <dje@google.com>
|
||||
|
||||
|
@ -6372,9 +6372,13 @@ For architecture environments that support process record and replay,
|
||||
@kindex record
|
||||
@kindex record full
|
||||
@kindex record btrace
|
||||
@kindex record btrace bts
|
||||
@kindex record bts
|
||||
@kindex rec
|
||||
@kindex rec full
|
||||
@kindex rec btrace
|
||||
@kindex rec btrace bts
|
||||
@kindex rec bts
|
||||
@item record @var{method}
|
||||
This command starts the process record and replay target. The
|
||||
recording method can be specified as parameter. Without a parameter
|
||||
@ -6387,13 +6391,25 @@ Full record/replay recording using @value{GDBN}'s software record and
|
||||
replay implementation. This method allows replaying and reverse
|
||||
execution.
|
||||
|
||||
@item btrace
|
||||
@item btrace @var{format}
|
||||
Hardware-supported instruction recording. This method does not record
|
||||
data. Further, the data is collected in a ring buffer so old data will
|
||||
be overwritten when the buffer is full. It allows limited replay and
|
||||
reverse execution.
|
||||
|
||||
This recording method may not be available on all processors.
|
||||
The recording format can be specified as parameter. Without a parameter
|
||||
the command chooses the recording format. The following recording
|
||||
formats are available:
|
||||
|
||||
@table @code
|
||||
@item bts
|
||||
@cindex branch trace store
|
||||
Use the @dfn{Branch Trace Store} (@acronym{BTS}) recording format. In
|
||||
this format, the processor stores a from/to record for each executed
|
||||
branch in the btrace ring buffer.
|
||||
@end table
|
||||
|
||||
Not all recording formats may be available on all processors.
|
||||
@end table
|
||||
|
||||
The process record and replay target can only debug a process that is
|
||||
@ -6571,9 +6587,9 @@ Maximum number of instructions that may be contained in the execution log.
|
||||
@end itemize
|
||||
|
||||
@item btrace
|
||||
For the @code{btrace} recording method, it shows the number of
|
||||
instructions that have been recorded and the number of blocks of
|
||||
sequential control-flow that is formed by the recorded instructions.
|
||||
For the @code{btrace} recording method, it shows the recording format,
|
||||
the number of instructions that have been recorded and the number of blocks
|
||||
of sequential control-flow that is formed by the recorded instructions.
|
||||
@end table
|
||||
|
||||
@kindex record delete
|
||||
@ -33066,7 +33082,8 @@ MS-Windows shared libraries (@pxref{Shared Libraries})
|
||||
@item
|
||||
Traceframe info (@pxref{Traceframe Info Format})
|
||||
@item
|
||||
Branch trace (@pxref{Branch Trace Format})
|
||||
Branch trace (@pxref{Branch Trace Format},
|
||||
@pxref{Branch Trace Configuration Format})
|
||||
@end itemize
|
||||
|
||||
@item zlib
|
||||
@ -34051,6 +34068,7 @@ Show the current setting of the target wait timeout.
|
||||
* Thread List Format::
|
||||
* Traceframe Info Format::
|
||||
* Branch Trace Format::
|
||||
* Branch Trace Configuration Format::
|
||||
@end menu
|
||||
|
||||
@node Overview
|
||||
@ -35723,6 +35741,11 @@ These are the currently defined stub features and their properties:
|
||||
@tab @samp{-}
|
||||
@tab Yes
|
||||
|
||||
@item @samp{qXfer:btrace-conf:read}
|
||||
@tab No
|
||||
@tab @samp{-}
|
||||
@tab Yes
|
||||
|
||||
@item @samp{qXfer:features:read}
|
||||
@tab No
|
||||
@tab @samp{-}
|
||||
@ -35907,6 +35930,10 @@ The remote stub understands the @samp{qXfer:auxv:read} packet
|
||||
The remote stub understands the @samp{qXfer:btrace:read}
|
||||
packet (@pxref{qXfer btrace read}).
|
||||
|
||||
@item qXfer:btrace-conf:read
|
||||
The remote stub understands the @samp{qXfer:btrace-conf:read}
|
||||
packet (@pxref{qXfer btrace-conf read}).
|
||||
|
||||
@item qXfer:features:read
|
||||
The remote stub understands the @samp{qXfer:features:read} packet
|
||||
(@pxref{qXfer target description read}).
|
||||
@ -36201,6 +36228,15 @@ If the trace buffer overflowed, returns an error indicating the overflow.
|
||||
This packet is not probed by default; the remote stub must request it
|
||||
by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}).
|
||||
|
||||
@item qXfer:btrace-conf:read::@var{offset},@var{length}
|
||||
@anchor{qXfer btrace-conf read}
|
||||
|
||||
Return a description of the current branch trace configuration.
|
||||
@xref{Branch Trace Configuration Format}.
|
||||
|
||||
This packet is not probed by default; the remote stub must request it
|
||||
by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}).
|
||||
|
||||
@item qXfer:features:read:@var{annex}:@var{offset},@var{length}
|
||||
@anchor{qXfer target description read}
|
||||
Access the @dfn{target description}. @xref{Target Descriptions}. The
|
||||
@ -39005,6 +39041,29 @@ The formal DTD for the branch trace format is given below:
|
||||
end CDATA #REQUIRED>
|
||||
@end smallexample
|
||||
|
||||
@node Branch Trace Configuration Format
|
||||
@section Branch Trace Configuration Format
|
||||
@cindex branch trace configuration format
|
||||
|
||||
For each inferior thread, @value{GDBN} can obtain the branch trace
|
||||
configuration using the @samp{qXfer:btrace-conf:read}
|
||||
(@pxref{qXfer btrace-conf read}) packet.
|
||||
|
||||
The configuration describes the branch trace format and configuration
|
||||
settings for that format.
|
||||
|
||||
@value{GDBN} must be linked with the Expat library to support XML
|
||||
branch trace configuration discovery. @xref{Expat}.
|
||||
|
||||
The formal DTD for the branch trace configuration format is given below:
|
||||
|
||||
@smallexample
|
||||
<!ELEMENT btrace-conf (bts?)>
|
||||
<!ATTLIST btrace-conf version CDATA #FIXED "1.0">
|
||||
|
||||
<!ELEMENT bts EMPTY>
|
||||
@end smallexample
|
||||
|
||||
@include agentexpr.texi
|
||||
|
||||
@node Target Descriptions
|
||||
|
10
gdb/features/btrace-conf.dtd
Normal file
10
gdb/features/btrace-conf.dtd
Normal file
@ -0,0 +1,10 @@
|
||||
<!-- Copyright (C) 2013-2015 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!ELEMENT btrace-conf (bts?)>
|
||||
<!ATTLIST btrace-conf version CDATA #FIXED "1.0">
|
||||
|
||||
<!ELEMENT bts EMPTY>
|
@ -1,3 +1,20 @@
|
||||
2015-02-09 Markus Metzger <markus.t.metzger@intel.com>
|
||||
|
||||
* linux-low.c (linux_low_enable_btrace): Update parameters.
|
||||
(linux_low_btrace_conf): New.
|
||||
(linux_target_ops)<to_btrace_conf>: Initialize.
|
||||
* server.c (current_btrace_conf): New.
|
||||
(handle_btrace_enable): Rename to ...
|
||||
(handle_btrace_enable_bts): ... this. Pass ¤t_btrace_conf
|
||||
to target_enable_btrace. Update comment. Update users.
|
||||
(handle_qxfer_btrace_conf): New.
|
||||
(qxfer_packets): Add btrace-conf entry.
|
||||
(handle_query): Report qXfer:btrace-conf:read as supported packet.
|
||||
* target.h (target_ops)<enable_btrace>: Update parameters and comment.
|
||||
(target_ops)<read_btrace_conf>: New.
|
||||
(target_enable_btrace): Update parameters.
|
||||
(target_read_btrace_conf): New.
|
||||
|
||||
2015-02-09 Markus Metzger <markus.t.metzger@intel.com>
|
||||
|
||||
* server.c (handle_btrace_general_set): Remove call to
|
||||
|
@ -5938,11 +5938,11 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
|
||||
/* See to_enable_btrace target method. */
|
||||
|
||||
static struct btrace_target_info *
|
||||
linux_low_enable_btrace (ptid_t ptid)
|
||||
linux_low_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
|
||||
{
|
||||
struct btrace_target_info *tinfo;
|
||||
|
||||
tinfo = linux_enable_btrace (ptid);
|
||||
tinfo = linux_enable_btrace (ptid, conf);
|
||||
|
||||
if (tinfo != NULL)
|
||||
{
|
||||
@ -6020,6 +6020,35 @@ linux_low_read_btrace (struct btrace_target_info *tinfo, struct buffer *buffer,
|
||||
btrace_data_fini (&btrace);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See to_btrace_conf target method. */
|
||||
|
||||
static int
|
||||
linux_low_btrace_conf (const struct btrace_target_info *tinfo,
|
||||
struct buffer *buffer)
|
||||
{
|
||||
const struct btrace_config *conf;
|
||||
|
||||
buffer_grow_str (buffer, "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n");
|
||||
buffer_grow_str (buffer, "<btrace-conf version=\"1.0\">\n");
|
||||
|
||||
conf = linux_btrace_conf (tinfo);
|
||||
if (conf != NULL)
|
||||
{
|
||||
switch (conf->format)
|
||||
{
|
||||
case BTRACE_FORMAT_NONE:
|
||||
break;
|
||||
|
||||
case BTRACE_FORMAT_BTS:
|
||||
buffer_xml_printf (buffer, "<bts/>\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buffer_grow_str0 (buffer, "</btrace-conf>\n");
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_LINUX_BTRACE */
|
||||
|
||||
static struct target_ops linux_target_ops = {
|
||||
@ -6093,11 +6122,13 @@ static struct target_ops linux_target_ops = {
|
||||
linux_low_enable_btrace,
|
||||
linux_low_disable_btrace,
|
||||
linux_low_read_btrace,
|
||||
linux_low_btrace_conf,
|
||||
#else
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
#endif
|
||||
linux_supports_range_stepping,
|
||||
};
|
||||
|
@ -122,6 +122,10 @@ struct vstop_notif
|
||||
struct target_waitstatus status;
|
||||
};
|
||||
|
||||
/* The current btrace configuration. This is gdbserver's mirror of GDB's
|
||||
btrace configuration. */
|
||||
static struct btrace_config current_btrace_conf;
|
||||
|
||||
DEFINE_QUEUE_P (notif_event_p);
|
||||
|
||||
/* Put a stop reply to the stop reply queue. */
|
||||
@ -381,15 +385,17 @@ write_qxfer_response (char *buf, const void *data, int len, int is_more)
|
||||
PBUFSIZ - 2) + 1;
|
||||
}
|
||||
|
||||
/* Handle btrace enabling. */
|
||||
/* Handle btrace enabling in BTS format. */
|
||||
|
||||
static const char *
|
||||
handle_btrace_enable (struct thread_info *thread)
|
||||
handle_btrace_enable_bts (struct thread_info *thread)
|
||||
{
|
||||
if (thread->btrace != NULL)
|
||||
return "E.Btrace already enabled.";
|
||||
|
||||
thread->btrace = target_enable_btrace (thread->entry.id);
|
||||
current_btrace_conf.format = BTRACE_FORMAT_BTS;
|
||||
thread->btrace = target_enable_btrace (thread->entry.id,
|
||||
¤t_btrace_conf);
|
||||
if (thread->btrace == NULL)
|
||||
return "E.Could not enable btrace.";
|
||||
|
||||
@ -443,7 +449,7 @@ handle_btrace_general_set (char *own_buf)
|
||||
err = NULL;
|
||||
|
||||
if (strcmp (op, "bts") == 0)
|
||||
err = handle_btrace_enable (thread);
|
||||
err = handle_btrace_enable_bts (thread);
|
||||
else if (strcmp (op, "off") == 0)
|
||||
err = handle_btrace_disable (thread);
|
||||
else
|
||||
@ -1510,10 +1516,73 @@ handle_qxfer_btrace (const char *annex,
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Handle qXfer:btrace-conf:read. */
|
||||
|
||||
static int
|
||||
handle_qxfer_btrace_conf (const char *annex,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||
ULONGEST offset, LONGEST len)
|
||||
{
|
||||
static struct buffer cache;
|
||||
struct thread_info *thread;
|
||||
int result;
|
||||
|
||||
if (the_target->read_btrace_conf == NULL || writebuf != NULL)
|
||||
return -2;
|
||||
|
||||
if (annex[0] != '\0' || !target_running ())
|
||||
return -1;
|
||||
|
||||
if (ptid_equal (general_thread, null_ptid)
|
||||
|| ptid_equal (general_thread, minus_one_ptid))
|
||||
{
|
||||
strcpy (own_buf, "E.Must select a single thread.");
|
||||
return -3;
|
||||
}
|
||||
|
||||
thread = find_thread_ptid (general_thread);
|
||||
if (thread == NULL)
|
||||
{
|
||||
strcpy (own_buf, "E.No such thread.");
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (thread->btrace == NULL)
|
||||
{
|
||||
strcpy (own_buf, "E.Btrace not enabled.");
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
buffer_free (&cache);
|
||||
|
||||
result = target_read_btrace_conf (thread->btrace, &cache);
|
||||
if (result != 0)
|
||||
{
|
||||
memcpy (own_buf, cache.buffer, cache.used_size);
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
else if (offset > cache.used_size)
|
||||
{
|
||||
buffer_free (&cache);
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (len > cache.used_size - offset)
|
||||
len = cache.used_size - offset;
|
||||
|
||||
memcpy (readbuf, cache.buffer + offset, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct qxfer qxfer_packets[] =
|
||||
{
|
||||
{ "auxv", handle_qxfer_auxv },
|
||||
{ "btrace", handle_qxfer_btrace },
|
||||
{ "btrace-conf", handle_qxfer_btrace_conf },
|
||||
{ "fdpic", handle_qxfer_fdpic},
|
||||
{ "features", handle_qxfer_features },
|
||||
{ "libraries", handle_qxfer_libraries },
|
||||
@ -1698,6 +1767,7 @@ supported_btrace_packets (char *buf)
|
||||
|
||||
strcat (buf, ";Qbtrace:off+");
|
||||
strcat (buf, ";qXfer:btrace:read+");
|
||||
strcat (buf, ";qXfer:btrace-conf:read+");
|
||||
}
|
||||
|
||||
/* Handle all of the extended 'q' packets. */
|
||||
|
@ -357,9 +357,10 @@ struct target_ops
|
||||
/* Check whether the target supports branch tracing. */
|
||||
int (*supports_btrace) (struct target_ops *, enum btrace_format);
|
||||
|
||||
/* Enable branch tracing for @ptid and allocate a branch trace target
|
||||
information struct for reading and for disabling branch trace. */
|
||||
struct btrace_target_info *(*enable_btrace) (ptid_t ptid);
|
||||
/* Enable branch tracing for PTID based on CONF and allocate a branch trace
|
||||
target information struct for reading and for disabling branch trace. */
|
||||
struct btrace_target_info *(*enable_btrace)
|
||||
(ptid_t ptid, const struct btrace_config *conf);
|
||||
|
||||
/* Disable branch tracing.
|
||||
Returns zero on success, non-zero otherwise. */
|
||||
@ -371,6 +372,11 @@ struct target_ops
|
||||
otherwise. */
|
||||
int (*read_btrace) (struct btrace_target_info *, struct buffer *, int type);
|
||||
|
||||
/* Read the branch trace configuration into BUFFER.
|
||||
Return 0 on success; print an error message into BUFFER and return -1
|
||||
otherwise. */
|
||||
int (*read_btrace_conf) (const struct btrace_target_info *, struct buffer *);
|
||||
|
||||
/* Return true if target supports range stepping. */
|
||||
int (*supports_range_stepping) (void);
|
||||
};
|
||||
@ -493,8 +499,8 @@ int kill_inferior (int);
|
||||
(the_target->supports_btrace \
|
||||
? (*the_target->supports_btrace) (the_target, format) : 0)
|
||||
|
||||
#define target_enable_btrace(ptid) \
|
||||
(*the_target->enable_btrace) (ptid)
|
||||
#define target_enable_btrace(ptid, conf) \
|
||||
(*the_target->enable_btrace) (ptid, conf)
|
||||
|
||||
#define target_disable_btrace(tinfo) \
|
||||
(*the_target->disable_btrace) (tinfo)
|
||||
@ -502,6 +508,9 @@ int kill_inferior (int);
|
||||
#define target_read_btrace(tinfo, buffer, type) \
|
||||
(*the_target->read_btrace) (tinfo, buffer, type)
|
||||
|
||||
#define target_read_btrace_conf(tinfo, buffer) \
|
||||
(*the_target->read_btrace_conf) (tinfo, buffer)
|
||||
|
||||
#define target_supports_range_stepping() \
|
||||
(the_target->supports_range_stepping ? \
|
||||
(*the_target->supports_range_stepping) () : 0)
|
||||
|
@ -90,8 +90,8 @@ perf_event_is_kernel_addr (const struct btrace_target_info *tinfo,
|
||||
/* Check whether a perf event record should be skipped. */
|
||||
|
||||
static inline int
|
||||
perf_event_skip_record (const struct btrace_target_info *tinfo,
|
||||
const struct perf_event_bts *bts)
|
||||
perf_event_skip_bts_record (const struct btrace_target_info *tinfo,
|
||||
const struct perf_event_bts *bts)
|
||||
{
|
||||
/* The hardware may report branches from kernel into user space. Branches
|
||||
from user into kernel space will be suppressed. We filter the former to
|
||||
@ -194,7 +194,7 @@ perf_event_read_bts (struct btrace_target_info* tinfo, const uint8_t *begin,
|
||||
break;
|
||||
}
|
||||
|
||||
if (perf_event_skip_record (tinfo, &psample->bts))
|
||||
if (perf_event_skip_bts_record (tinfo, &psample->bts))
|
||||
continue;
|
||||
|
||||
/* We found a valid sample, so we can complete the current block. */
|
||||
@ -395,39 +395,42 @@ linux_supports_btrace (struct target_ops *ops, enum btrace_format format)
|
||||
internal_error (__FILE__, __LINE__, _("Unknown branch trace format"));
|
||||
}
|
||||
|
||||
/* See linux-btrace.h. */
|
||||
/* Enable branch tracing in BTS format. */
|
||||
|
||||
struct btrace_target_info *
|
||||
linux_enable_btrace (ptid_t ptid)
|
||||
static struct btrace_target_info *
|
||||
linux_enable_bts (ptid_t ptid, const struct btrace_config *conf)
|
||||
{
|
||||
struct perf_event_mmap_page *header;
|
||||
struct btrace_target_info *tinfo;
|
||||
struct btrace_tinfo_bts *bts;
|
||||
int pid, pg;
|
||||
|
||||
tinfo = xzalloc (sizeof (*tinfo));
|
||||
tinfo->ptid = ptid;
|
||||
tinfo->ptr_bits = 0;
|
||||
|
||||
tinfo->attr.size = sizeof (tinfo->attr);
|
||||
tinfo->attr.type = PERF_TYPE_HARDWARE;
|
||||
tinfo->attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
|
||||
tinfo->attr.sample_period = 1;
|
||||
tinfo->conf.format = BTRACE_FORMAT_BTS;
|
||||
bts = &tinfo->variant.bts;
|
||||
|
||||
bts->attr.size = sizeof (bts->attr);
|
||||
bts->attr.type = PERF_TYPE_HARDWARE;
|
||||
bts->attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
|
||||
bts->attr.sample_period = 1;
|
||||
|
||||
/* We sample from and to address. */
|
||||
tinfo->attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_ADDR;
|
||||
bts->attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_ADDR;
|
||||
|
||||
tinfo->attr.exclude_kernel = 1;
|
||||
tinfo->attr.exclude_hv = 1;
|
||||
tinfo->attr.exclude_idle = 1;
|
||||
|
||||
tinfo->ptr_bits = 0;
|
||||
bts->attr.exclude_kernel = 1;
|
||||
bts->attr.exclude_hv = 1;
|
||||
bts->attr.exclude_idle = 1;
|
||||
|
||||
pid = ptid_get_lwp (ptid);
|
||||
if (pid == 0)
|
||||
pid = ptid_get_pid (ptid);
|
||||
|
||||
errno = 0;
|
||||
tinfo->file = syscall (SYS_perf_event_open, &tinfo->attr, pid, -1, -1, 0);
|
||||
if (tinfo->file < 0)
|
||||
bts->file = syscall (SYS_perf_event_open, &bts->attr, pid, -1, -1, 0);
|
||||
if (bts->file < 0)
|
||||
goto err;
|
||||
|
||||
/* We try to allocate as much buffer as we can get.
|
||||
@ -437,7 +440,7 @@ linux_enable_btrace (ptid_t ptid)
|
||||
{
|
||||
/* The number of pages we request needs to be a power of two. */
|
||||
header = mmap (NULL, ((1 << pg) + 1) * PAGE_SIZE, PROT_READ, MAP_SHARED,
|
||||
tinfo->file, 0);
|
||||
bts->file, 0);
|
||||
if (header != MAP_FAILED)
|
||||
break;
|
||||
}
|
||||
@ -445,17 +448,17 @@ linux_enable_btrace (ptid_t ptid)
|
||||
if (header == MAP_FAILED)
|
||||
goto err_file;
|
||||
|
||||
tinfo->header = header;
|
||||
tinfo->bts.mem = ((const uint8_t *) header) + PAGE_SIZE;
|
||||
tinfo->bts.size = (1 << pg) * PAGE_SIZE;
|
||||
tinfo->bts.data_head = &header->data_head;
|
||||
tinfo->bts.last_head = 0;
|
||||
bts->header = header;
|
||||
bts->bts.mem = ((const uint8_t *) header) + PAGE_SIZE;
|
||||
bts->bts.size = (1 << pg) * PAGE_SIZE;
|
||||
bts->bts.data_head = &header->data_head;
|
||||
bts->bts.last_head = 0;
|
||||
|
||||
return tinfo;
|
||||
|
||||
err_file:
|
||||
/* We were not able to allocate any buffer. */
|
||||
close (tinfo->file);
|
||||
close (bts->file);
|
||||
|
||||
err:
|
||||
xfree (tinfo);
|
||||
@ -464,16 +467,60 @@ linux_enable_btrace (ptid_t ptid)
|
||||
|
||||
/* See linux-btrace.h. */
|
||||
|
||||
enum btrace_error
|
||||
linux_disable_btrace (struct btrace_target_info *tinfo)
|
||||
struct btrace_target_info *
|
||||
linux_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
|
||||
{
|
||||
struct btrace_target_info *tinfo;
|
||||
|
||||
tinfo = NULL;
|
||||
switch (conf->format)
|
||||
{
|
||||
case BTRACE_FORMAT_NONE:
|
||||
break;
|
||||
|
||||
case BTRACE_FORMAT_BTS:
|
||||
tinfo = linux_enable_bts (ptid, conf);
|
||||
break;
|
||||
}
|
||||
|
||||
return tinfo;
|
||||
}
|
||||
|
||||
/* Disable BTS tracing. */
|
||||
|
||||
static enum btrace_error
|
||||
linux_disable_bts (struct btrace_tinfo_bts *tinfo)
|
||||
{
|
||||
munmap((void *) tinfo->header, tinfo->bts.size + PAGE_SIZE);
|
||||
close (tinfo->file);
|
||||
xfree (tinfo);
|
||||
|
||||
return BTRACE_ERR_NONE;
|
||||
}
|
||||
|
||||
/* See linux-btrace.h. */
|
||||
|
||||
enum btrace_error
|
||||
linux_disable_btrace (struct btrace_target_info *tinfo)
|
||||
{
|
||||
enum btrace_error errcode;
|
||||
|
||||
errcode = BTRACE_ERR_NOT_SUPPORTED;
|
||||
switch (tinfo->conf.format)
|
||||
{
|
||||
case BTRACE_FORMAT_NONE:
|
||||
break;
|
||||
|
||||
case BTRACE_FORMAT_BTS:
|
||||
errcode = linux_disable_bts (&tinfo->variant.bts);
|
||||
break;
|
||||
}
|
||||
|
||||
if (errcode == BTRACE_ERR_NONE)
|
||||
xfree (tinfo);
|
||||
|
||||
return errcode;
|
||||
}
|
||||
|
||||
/* Read branch trace data in BTS format for the thread given by TINFO into
|
||||
BTRACE using the TYPE reading method. */
|
||||
|
||||
@ -487,7 +534,7 @@ linux_read_bts (struct btrace_data_bts *btrace,
|
||||
unsigned long long data_head, data_tail, buffer_size, size;
|
||||
unsigned int retries = 5;
|
||||
|
||||
pevent = &tinfo->bts;
|
||||
pevent = &tinfo->variant.bts.bts;
|
||||
|
||||
/* For delta reads, we return at least the partial last block containing
|
||||
the current PC. */
|
||||
@ -570,11 +617,28 @@ linux_read_btrace (struct btrace_data *btrace,
|
||||
struct btrace_target_info *tinfo,
|
||||
enum btrace_read_type type)
|
||||
{
|
||||
/* We read btrace in BTS format. */
|
||||
btrace->format = BTRACE_FORMAT_BTS;
|
||||
btrace->variant.bts.blocks = NULL;
|
||||
switch (tinfo->conf.format)
|
||||
{
|
||||
case BTRACE_FORMAT_NONE:
|
||||
return BTRACE_ERR_NOT_SUPPORTED;
|
||||
|
||||
return linux_read_bts (&btrace->variant.bts, tinfo, type);
|
||||
case BTRACE_FORMAT_BTS:
|
||||
/* We read btrace in BTS format. */
|
||||
btrace->format = BTRACE_FORMAT_BTS;
|
||||
btrace->variant.bts.blocks = NULL;
|
||||
|
||||
return linux_read_bts (&btrace->variant.bts, tinfo, type);
|
||||
}
|
||||
|
||||
internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
|
||||
}
|
||||
|
||||
/* See linux-btrace.h. */
|
||||
|
||||
const struct btrace_config *
|
||||
linux_btrace_conf (const struct btrace_target_info *tinfo)
|
||||
{
|
||||
return &tinfo->conf;
|
||||
}
|
||||
|
||||
#else /* !HAVE_LINUX_PERF_EVENT_H */
|
||||
@ -590,7 +654,7 @@ linux_supports_btrace (struct target_ops *ops, enum btrace_format format)
|
||||
/* See linux-btrace.h. */
|
||||
|
||||
struct btrace_target_info *
|
||||
linux_enable_btrace (ptid_t ptid)
|
||||
linux_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@ -613,4 +677,12 @@ linux_read_btrace (struct btrace_data *btrace,
|
||||
return BTRACE_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* See linux-btrace.h. */
|
||||
|
||||
const struct btrace_config *
|
||||
linux_btrace_conf (const struct btrace_target_info *tinfo)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_LINUX_PERF_EVENT_H */
|
||||
|
@ -48,18 +48,13 @@ struct perf_event_buffer
|
||||
/* The data_head value from the last read. */
|
||||
unsigned long long last_head;
|
||||
};
|
||||
#endif /* HAVE_LINUX_PERF_EVENT_H */
|
||||
|
||||
/* Branch trace target information per thread. */
|
||||
struct btrace_target_info
|
||||
/* Branch trace target information for BTS tracing. */
|
||||
struct btrace_tinfo_bts
|
||||
{
|
||||
#if HAVE_LINUX_PERF_EVENT_H
|
||||
/* The Linux perf_event configuration for collecting the branch trace. */
|
||||
struct perf_event_attr attr;
|
||||
|
||||
/* The ptid of this thread. */
|
||||
ptid_t ptid;
|
||||
|
||||
/* The perf event file. */
|
||||
int file;
|
||||
|
||||
@ -68,6 +63,25 @@ struct btrace_target_info
|
||||
|
||||
/* The BTS perf event buffer. */
|
||||
struct perf_event_buffer bts;
|
||||
};
|
||||
#endif /* HAVE_LINUX_PERF_EVENT_H */
|
||||
|
||||
/* Branch trace target information per thread. */
|
||||
struct btrace_target_info
|
||||
{
|
||||
/* The ptid of this thread. */
|
||||
ptid_t ptid;
|
||||
|
||||
/* The obtained branch trace configuration. */
|
||||
struct btrace_config conf;
|
||||
|
||||
#if HAVE_LINUX_PERF_EVENT_H
|
||||
/* The branch tracing format specific information. */
|
||||
union
|
||||
{
|
||||
/* CONF.FORMAT == BTRACE_FORMAT_BTS. */
|
||||
struct btrace_tinfo_bts bts;
|
||||
} variant;
|
||||
#endif /* HAVE_LINUX_PERF_EVENT_H */
|
||||
|
||||
/* The size of a pointer in bits for this thread.
|
||||
@ -80,7 +94,8 @@ struct btrace_target_info
|
||||
extern int linux_supports_btrace (struct target_ops *, enum btrace_format);
|
||||
|
||||
/* See to_enable_btrace in target.h. */
|
||||
extern struct btrace_target_info *linux_enable_btrace (ptid_t ptid);
|
||||
extern struct btrace_target_info *
|
||||
linux_enable_btrace (ptid_t ptid, const struct btrace_config *conf);
|
||||
|
||||
/* See to_disable_btrace in target.h. */
|
||||
extern enum btrace_error linux_disable_btrace (struct btrace_target_info *ti);
|
||||
@ -90,4 +105,8 @@ extern enum btrace_error linux_read_btrace (struct btrace_data *btrace,
|
||||
struct btrace_target_info *btinfo,
|
||||
enum btrace_read_type type);
|
||||
|
||||
/* See to_btrace_conf in target.h. */
|
||||
extern const struct btrace_config *
|
||||
linux_btrace_conf (const struct btrace_target_info *);
|
||||
|
||||
#endif /* LINUX_BTRACE_H */
|
||||
|
@ -70,6 +70,12 @@ static struct async_event_handler *record_btrace_async_inferior_event_handler;
|
||||
/* A flag indicating that we are currently generating a core file. */
|
||||
static int record_btrace_generating_corefile;
|
||||
|
||||
/* The current branch trace configuration. */
|
||||
static struct btrace_config record_btrace_conf;
|
||||
|
||||
/* Command list for "record btrace". */
|
||||
static struct cmd_list_element *record_btrace_cmdlist;
|
||||
|
||||
/* Print a record-btrace debug message. Use do ... while (0) to avoid
|
||||
ambiguities when used in if statements. */
|
||||
|
||||
@ -132,7 +138,7 @@ record_btrace_enable_warn (struct thread_info *tp)
|
||||
volatile struct gdb_exception error;
|
||||
|
||||
TRY_CATCH (error, RETURN_MASK_ERROR)
|
||||
btrace_enable (tp);
|
||||
btrace_enable (tp, &record_btrace_conf);
|
||||
|
||||
if (error.message != NULL)
|
||||
warning ("%s", error.message);
|
||||
@ -208,7 +214,7 @@ record_btrace_open (const char *args, int from_tty)
|
||||
ALL_NON_EXITED_THREADS (tp)
|
||||
if (args == NULL || *args == 0 || number_is_in_list (args, tp->num))
|
||||
{
|
||||
btrace_enable (tp);
|
||||
btrace_enable (tp, &record_btrace_conf);
|
||||
|
||||
make_cleanup (record_btrace_disable_callback, tp);
|
||||
}
|
||||
@ -285,6 +291,7 @@ static void
|
||||
record_btrace_info (struct target_ops *self)
|
||||
{
|
||||
struct btrace_thread_info *btinfo;
|
||||
const struct btrace_config *conf;
|
||||
struct thread_info *tp;
|
||||
unsigned int insns, calls;
|
||||
|
||||
@ -294,13 +301,18 @@ record_btrace_info (struct target_ops *self)
|
||||
if (tp == NULL)
|
||||
error (_("No thread."));
|
||||
|
||||
btinfo = &tp->btrace;
|
||||
|
||||
conf = btrace_conf (btinfo);
|
||||
if (conf != NULL)
|
||||
printf_unfiltered (_("Recording format: %s.\n"),
|
||||
btrace_format_string (conf->format));
|
||||
|
||||
btrace_fetch (tp);
|
||||
|
||||
insns = 0;
|
||||
calls = 0;
|
||||
|
||||
btinfo = &tp->btrace;
|
||||
|
||||
if (!btrace_is_empty (tp))
|
||||
{
|
||||
struct btrace_call_iterator call;
|
||||
@ -1991,15 +2003,48 @@ init_record_btrace_ops (void)
|
||||
ops->to_magic = OPS_MAGIC;
|
||||
}
|
||||
|
||||
/* Start recording in BTS format. */
|
||||
|
||||
static void
|
||||
cmd_record_btrace_bts_start (char *args, int from_tty)
|
||||
{
|
||||
volatile struct gdb_exception exception;
|
||||
|
||||
if (args != NULL && *args != 0)
|
||||
error (_("Invalid argument."));
|
||||
|
||||
record_btrace_conf.format = BTRACE_FORMAT_BTS;
|
||||
|
||||
TRY_CATCH (exception, RETURN_MASK_ALL)
|
||||
execute_command ("target record-btrace", from_tty);
|
||||
|
||||
if (exception.error != 0)
|
||||
{
|
||||
record_btrace_conf.format = BTRACE_FORMAT_NONE;
|
||||
throw_exception (exception);
|
||||
}
|
||||
}
|
||||
|
||||
/* Alias for "target record". */
|
||||
|
||||
static void
|
||||
cmd_record_btrace_start (char *args, int from_tty)
|
||||
{
|
||||
volatile struct gdb_exception exception;
|
||||
|
||||
if (args != NULL && *args != 0)
|
||||
error (_("Invalid argument."));
|
||||
|
||||
execute_command ("target record-btrace", from_tty);
|
||||
record_btrace_conf.format = BTRACE_FORMAT_BTS;
|
||||
|
||||
TRY_CATCH (exception, RETURN_MASK_ALL)
|
||||
execute_command ("target record-btrace", from_tty);
|
||||
|
||||
if (exception.error == 0)
|
||||
return;
|
||||
|
||||
record_btrace_conf.format = BTRACE_FORMAT_NONE;
|
||||
throw_exception (exception);
|
||||
}
|
||||
|
||||
/* The "set record btrace" command. */
|
||||
@ -2035,11 +2080,19 @@ void _initialize_record_btrace (void);
|
||||
void
|
||||
_initialize_record_btrace (void)
|
||||
{
|
||||
add_cmd ("btrace", class_obscure, cmd_record_btrace_start,
|
||||
_("Start branch trace recording."),
|
||||
&record_cmdlist);
|
||||
add_prefix_cmd ("btrace", class_obscure, cmd_record_btrace_start,
|
||||
_("Start branch trace recording."), &record_btrace_cmdlist,
|
||||
"record btrace ", 0, &record_cmdlist);
|
||||
add_alias_cmd ("b", "btrace", class_obscure, 1, &record_cmdlist);
|
||||
|
||||
add_cmd ("bts", class_obscure, cmd_record_btrace_bts_start,
|
||||
_("\
|
||||
Start branch trace recording in Branch Trace Store (BTS) format.\n\n\
|
||||
The processor stores a from/to record for each branch into a cyclic buffer.\n\
|
||||
This format may not be available on all processors."),
|
||||
&record_btrace_cmdlist);
|
||||
add_alias_cmd ("bts", "btrace bts", class_obscure, 1, &record_cmdlist);
|
||||
|
||||
add_prefix_cmd ("btrace", class_support, cmd_set_record_btrace,
|
||||
_("Set record options"), &set_record_btrace_cmdlist,
|
||||
"set record btrace ", 0, &set_record_cmdlist);
|
||||
|
85
gdb/remote.c
85
gdb/remote.c
@ -221,6 +221,8 @@ static int remote_supports_cond_breakpoints (struct target_ops *self);
|
||||
|
||||
static int remote_can_run_breakpoint_commands (struct target_ops *self);
|
||||
|
||||
static void remote_btrace_reset (void);
|
||||
|
||||
/* For "remote". */
|
||||
|
||||
static struct cmd_list_element *remote_cmdlist;
|
||||
@ -371,6 +373,9 @@ struct remote_state
|
||||
|
||||
/* The state of remote notification. */
|
||||
struct remote_notif_state *notif_state;
|
||||
|
||||
/* The branch trace configuration. */
|
||||
struct btrace_config btrace_config;
|
||||
};
|
||||
|
||||
/* Private data that we'll store in (struct thread_info)->private. */
|
||||
@ -1327,6 +1332,9 @@ enum {
|
||||
/* Support for qXfer:libraries-svr4:read with a non-empty annex. */
|
||||
PACKET_augmented_libraries_svr4_read_feature,
|
||||
|
||||
/* Support for the qXfer:btrace-conf:read packet. */
|
||||
PACKET_qXfer_btrace_conf,
|
||||
|
||||
PACKET_MAX
|
||||
};
|
||||
|
||||
@ -4010,7 +4018,9 @@ static const struct protocol_feature remote_protocol_features[] = {
|
||||
{ "Qbtrace:off", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace_off },
|
||||
{ "Qbtrace:bts", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace_bts },
|
||||
{ "qXfer:btrace:read", PACKET_DISABLE, remote_supported_packet,
|
||||
PACKET_qXfer_btrace }
|
||||
PACKET_qXfer_btrace },
|
||||
{ "qXfer:btrace-conf:read", PACKET_DISABLE, remote_supported_packet,
|
||||
PACKET_qXfer_btrace_conf }
|
||||
};
|
||||
|
||||
static char *remote_support_xml;
|
||||
@ -4358,6 +4368,8 @@ remote_open_1 (const char *name, int from_tty,
|
||||
}
|
||||
}
|
||||
|
||||
remote_btrace_reset ();
|
||||
|
||||
if (target_async_permitted)
|
||||
wait_forever_enabled_p = 1;
|
||||
}
|
||||
@ -8945,6 +8957,11 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
|
||||
xfered_len,
|
||||
&remote_protocol_packets[PACKET_qXfer_btrace]);
|
||||
|
||||
case TARGET_OBJECT_BTRACE_CONF:
|
||||
return remote_read_qxfer (ops, "btrace-conf", annex, readbuf, offset,
|
||||
len, xfered_len,
|
||||
&remote_protocol_packets[PACKET_qXfer_btrace_conf]);
|
||||
|
||||
default:
|
||||
return TARGET_XFER_E_IO;
|
||||
}
|
||||
@ -11319,8 +11336,21 @@ struct btrace_target_info
|
||||
{
|
||||
/* The ptid of the traced thread. */
|
||||
ptid_t ptid;
|
||||
|
||||
/* The obtained branch trace configuration. */
|
||||
struct btrace_config conf;
|
||||
};
|
||||
|
||||
/* Reset our idea of our target's btrace configuration. */
|
||||
|
||||
static void
|
||||
remote_btrace_reset (void)
|
||||
{
|
||||
struct remote_state *rs = get_remote_state ();
|
||||
|
||||
memset (&rs->btrace_config, 0, sizeof (rs->btrace_config));
|
||||
}
|
||||
|
||||
/* Check whether the target supports branch tracing. */
|
||||
|
||||
static int
|
||||
@ -11343,20 +11373,52 @@ remote_supports_btrace (struct target_ops *self, enum btrace_format format)
|
||||
internal_error (__FILE__, __LINE__, _("Unknown branch trace format"));
|
||||
}
|
||||
|
||||
/* Synchronize the configuration with the target. */
|
||||
|
||||
static void
|
||||
btrace_sync_conf (const struct btrace_config *conf)
|
||||
{
|
||||
/* Nothing to do for now. */
|
||||
}
|
||||
|
||||
/* Read the current thread's btrace configuration from the target and
|
||||
store it into CONF. */
|
||||
|
||||
static void
|
||||
btrace_read_config (struct btrace_config *conf)
|
||||
{
|
||||
char *xml;
|
||||
|
||||
xml = target_read_stralloc (¤t_target,
|
||||
TARGET_OBJECT_BTRACE_CONF, "");
|
||||
if (xml != NULL)
|
||||
{
|
||||
struct cleanup *cleanup;
|
||||
|
||||
cleanup = make_cleanup (xfree, xml);
|
||||
parse_xml_btrace_conf (conf, xml);
|
||||
do_cleanups (cleanup);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable branch tracing. */
|
||||
|
||||
static struct btrace_target_info *
|
||||
remote_enable_btrace (struct target_ops *self, ptid_t ptid)
|
||||
remote_enable_btrace (struct target_ops *self, ptid_t ptid,
|
||||
const struct btrace_config *conf)
|
||||
{
|
||||
struct btrace_target_info *tinfo = NULL;
|
||||
struct packet_config *packet = &remote_protocol_packets[PACKET_Qbtrace_bts];
|
||||
struct remote_state *rs = get_remote_state ();
|
||||
char *buf = rs->buf;
|
||||
char *endbuf = rs->buf + get_remote_packet_size ();
|
||||
volatile struct gdb_exception err;
|
||||
|
||||
if (packet_config_support (packet) != PACKET_ENABLE)
|
||||
error (_("Target does not support branch tracing."));
|
||||
|
||||
btrace_sync_conf (conf);
|
||||
|
||||
set_general_thread (ptid);
|
||||
|
||||
buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
|
||||
@ -11376,6 +11438,14 @@ remote_enable_btrace (struct target_ops *self, ptid_t ptid)
|
||||
tinfo = xzalloc (sizeof (*tinfo));
|
||||
tinfo->ptid = ptid;
|
||||
|
||||
/* If we fail to read the configuration, we lose some information, but the
|
||||
tracing itself is not impacted. */
|
||||
TRY_CATCH (err, RETURN_MASK_ERROR)
|
||||
btrace_read_config (&tinfo->conf);
|
||||
|
||||
if (err.message != NULL)
|
||||
warning ("%s", err.message);
|
||||
|
||||
return tinfo;
|
||||
}
|
||||
|
||||
@ -11472,6 +11542,13 @@ remote_read_btrace (struct target_ops *self,
|
||||
return BTRACE_ERR_NONE;
|
||||
}
|
||||
|
||||
static const struct btrace_config *
|
||||
remote_btrace_conf (struct target_ops *self,
|
||||
const struct btrace_target_info *tinfo)
|
||||
{
|
||||
return &tinfo->conf;
|
||||
}
|
||||
|
||||
static int
|
||||
remote_augmented_libraries_svr4_read (struct target_ops *self)
|
||||
{
|
||||
@ -11608,6 +11685,7 @@ Specify the serial device it is connected to\n\
|
||||
remote_ops.to_disable_btrace = remote_disable_btrace;
|
||||
remote_ops.to_teardown_btrace = remote_teardown_btrace;
|
||||
remote_ops.to_read_btrace = remote_read_btrace;
|
||||
remote_ops.to_btrace_conf = remote_btrace_conf;
|
||||
remote_ops.to_augmented_libraries_svr4_read =
|
||||
remote_augmented_libraries_svr4_read;
|
||||
}
|
||||
@ -12206,6 +12284,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
|
||||
add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace],
|
||||
"qXfer:btrace", "read-btrace", 0);
|
||||
|
||||
add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace_conf],
|
||||
"qXfer:btrace-conf", "read-btrace-conf", 0);
|
||||
|
||||
/* Assert that we've registered commands for all packet configs. */
|
||||
{
|
||||
int i;
|
||||
|
@ -148,6 +148,10 @@
|
||||
target_debug_do_print (host_address_to_string (X))
|
||||
#define target_debug_print_enum_btrace_format(X) \
|
||||
target_debug_do_print (plongest (X))
|
||||
#define target_debug_print_const_struct_btrace_config_p(X) \
|
||||
target_debug_do_print (host_address_to_string (X))
|
||||
#define target_debug_print_const_struct_btrace_target_info_p(X) \
|
||||
target_debug_do_print (host_address_to_string (X))
|
||||
|
||||
static void
|
||||
target_debug_print_struct_target_waitstatus_p (struct target_waitstatus *status)
|
||||
|
@ -3114,28 +3114,30 @@ debug_supports_btrace (struct target_ops *self, enum btrace_format arg1)
|
||||
}
|
||||
|
||||
static struct btrace_target_info *
|
||||
delegate_enable_btrace (struct target_ops *self, ptid_t arg1)
|
||||
delegate_enable_btrace (struct target_ops *self, ptid_t arg1, const struct btrace_config *arg2)
|
||||
{
|
||||
self = self->beneath;
|
||||
return self->to_enable_btrace (self, arg1);
|
||||
return self->to_enable_btrace (self, arg1, arg2);
|
||||
}
|
||||
|
||||
static struct btrace_target_info *
|
||||
tdefault_enable_btrace (struct target_ops *self, ptid_t arg1)
|
||||
tdefault_enable_btrace (struct target_ops *self, ptid_t arg1, const struct btrace_config *arg2)
|
||||
{
|
||||
tcomplain ();
|
||||
}
|
||||
|
||||
static struct btrace_target_info *
|
||||
debug_enable_btrace (struct target_ops *self, ptid_t arg1)
|
||||
debug_enable_btrace (struct target_ops *self, ptid_t arg1, const struct btrace_config *arg2)
|
||||
{
|
||||
struct btrace_target_info * result;
|
||||
fprintf_unfiltered (gdb_stdlog, "-> %s->to_enable_btrace (...)\n", debug_target.to_shortname);
|
||||
result = debug_target.to_enable_btrace (&debug_target, arg1);
|
||||
result = debug_target.to_enable_btrace (&debug_target, arg1, arg2);
|
||||
fprintf_unfiltered (gdb_stdlog, "<- %s->to_enable_btrace (", debug_target.to_shortname);
|
||||
target_debug_print_struct_target_ops_p (&debug_target);
|
||||
fputs_unfiltered (", ", gdb_stdlog);
|
||||
target_debug_print_ptid_t (arg1);
|
||||
fputs_unfiltered (", ", gdb_stdlog);
|
||||
target_debug_print_const_struct_btrace_config_p (arg2);
|
||||
fputs_unfiltered (") = ", gdb_stdlog);
|
||||
target_debug_print_struct_btrace_target_info_p (result);
|
||||
fputs_unfiltered ("\n", gdb_stdlog);
|
||||
@ -3225,6 +3227,35 @@ debug_read_btrace (struct target_ops *self, struct btrace_data *arg1, struct btr
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct btrace_config *
|
||||
delegate_btrace_conf (struct target_ops *self, const struct btrace_target_info *arg1)
|
||||
{
|
||||
self = self->beneath;
|
||||
return self->to_btrace_conf (self, arg1);
|
||||
}
|
||||
|
||||
static const struct btrace_config *
|
||||
tdefault_btrace_conf (struct target_ops *self, const struct btrace_target_info *arg1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct btrace_config *
|
||||
debug_btrace_conf (struct target_ops *self, const struct btrace_target_info *arg1)
|
||||
{
|
||||
const struct btrace_config * result;
|
||||
fprintf_unfiltered (gdb_stdlog, "-> %s->to_btrace_conf (...)\n", debug_target.to_shortname);
|
||||
result = debug_target.to_btrace_conf (&debug_target, arg1);
|
||||
fprintf_unfiltered (gdb_stdlog, "<- %s->to_btrace_conf (", debug_target.to_shortname);
|
||||
target_debug_print_struct_target_ops_p (&debug_target);
|
||||
fputs_unfiltered (", ", gdb_stdlog);
|
||||
target_debug_print_const_struct_btrace_target_info_p (arg1);
|
||||
fputs_unfiltered (") = ", gdb_stdlog);
|
||||
target_debug_print_const_struct_btrace_config_p (result);
|
||||
fputs_unfiltered ("\n", gdb_stdlog);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_stop_recording (struct target_ops *self)
|
||||
{
|
||||
@ -3972,6 +4003,8 @@ install_delegators (struct target_ops *ops)
|
||||
ops->to_teardown_btrace = delegate_teardown_btrace;
|
||||
if (ops->to_read_btrace == NULL)
|
||||
ops->to_read_btrace = delegate_read_btrace;
|
||||
if (ops->to_btrace_conf == NULL)
|
||||
ops->to_btrace_conf = delegate_btrace_conf;
|
||||
if (ops->to_stop_recording == NULL)
|
||||
ops->to_stop_recording = delegate_stop_recording;
|
||||
if (ops->to_info_record == NULL)
|
||||
@ -4135,6 +4168,7 @@ install_dummy_methods (struct target_ops *ops)
|
||||
ops->to_disable_btrace = tdefault_disable_btrace;
|
||||
ops->to_teardown_btrace = tdefault_teardown_btrace;
|
||||
ops->to_read_btrace = tdefault_read_btrace;
|
||||
ops->to_btrace_conf = tdefault_btrace_conf;
|
||||
ops->to_stop_recording = tdefault_stop_recording;
|
||||
ops->to_info_record = tdefault_info_record;
|
||||
ops->to_save_record = tdefault_save_record;
|
||||
@ -4278,6 +4312,7 @@ init_debug_target (struct target_ops *ops)
|
||||
ops->to_disable_btrace = debug_disable_btrace;
|
||||
ops->to_teardown_btrace = debug_teardown_btrace;
|
||||
ops->to_read_btrace = debug_read_btrace;
|
||||
ops->to_btrace_conf = debug_btrace_conf;
|
||||
ops->to_stop_recording = debug_stop_recording;
|
||||
ops->to_info_record = debug_info_record;
|
||||
ops->to_save_record = debug_save_record;
|
||||
|
12
gdb/target.c
12
gdb/target.c
@ -3398,9 +3398,9 @@ target_supports_btrace (enum btrace_format format)
|
||||
/* See target.h. */
|
||||
|
||||
struct btrace_target_info *
|
||||
target_enable_btrace (ptid_t ptid)
|
||||
target_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
|
||||
{
|
||||
return current_target.to_enable_btrace (¤t_target, ptid);
|
||||
return current_target.to_enable_btrace (¤t_target, ptid, conf);
|
||||
}
|
||||
|
||||
/* See target.h. */
|
||||
@ -3431,6 +3431,14 @@ target_read_btrace (struct btrace_data *btrace,
|
||||
|
||||
/* See target.h. */
|
||||
|
||||
const struct btrace_config *
|
||||
target_btrace_conf (const struct btrace_target_info *btinfo)
|
||||
{
|
||||
return current_target.to_btrace_conf (¤t_target, btinfo);
|
||||
}
|
||||
|
||||
/* See target.h. */
|
||||
|
||||
void
|
||||
target_stop_recording (void)
|
||||
{
|
||||
|
24
gdb/target.h
24
gdb/target.h
@ -200,7 +200,9 @@ enum target_object
|
||||
/* OpenVMS Unwind Information Block. */
|
||||
TARGET_OBJECT_OPENVMS_UIB,
|
||||
/* Branch trace data, in XML format. */
|
||||
TARGET_OBJECT_BTRACE
|
||||
TARGET_OBJECT_BTRACE,
|
||||
/* Branch trace configuration, in XML format. */
|
||||
TARGET_OBJECT_BTRACE_CONF
|
||||
/* Possible future objects: TARGET_OBJECT_FILE, ... */
|
||||
};
|
||||
|
||||
@ -1002,10 +1004,12 @@ struct target_ops
|
||||
int (*to_supports_btrace) (struct target_ops *, enum btrace_format)
|
||||
TARGET_DEFAULT_RETURN (0);
|
||||
|
||||
/* Enable branch tracing for PTID and allocate a branch trace target
|
||||
information struct for reading and for disabling branch trace. */
|
||||
/* Enable branch tracing for PTID using CONF configuration.
|
||||
Return a branch trace target information struct for reading and for
|
||||
disabling branch trace. */
|
||||
struct btrace_target_info *(*to_enable_btrace) (struct target_ops *,
|
||||
ptid_t ptid)
|
||||
ptid_t ptid,
|
||||
const struct btrace_config *conf)
|
||||
TARGET_DEFAULT_NORETURN (tcomplain ());
|
||||
|
||||
/* Disable branch tracing and deallocate TINFO. */
|
||||
@ -1029,6 +1033,11 @@ struct target_ops
|
||||
enum btrace_read_type type)
|
||||
TARGET_DEFAULT_NORETURN (tcomplain ());
|
||||
|
||||
/* Get the branch trace configuration. */
|
||||
const struct btrace_config *(*to_btrace_conf) (struct target_ops *self,
|
||||
const struct btrace_target_info *)
|
||||
TARGET_DEFAULT_RETURN (NULL);
|
||||
|
||||
/* Stop trace recording. */
|
||||
void (*to_stop_recording) (struct target_ops *)
|
||||
TARGET_DEFAULT_IGNORE ();
|
||||
@ -2218,7 +2227,8 @@ extern void update_target_permissions (void);
|
||||
extern int target_supports_btrace (enum btrace_format);
|
||||
|
||||
/* See to_enable_btrace in struct target_ops. */
|
||||
extern struct btrace_target_info *target_enable_btrace (ptid_t ptid);
|
||||
extern struct btrace_target_info *
|
||||
target_enable_btrace (ptid_t ptid, const struct btrace_config *);
|
||||
|
||||
/* See to_disable_btrace in struct target_ops. */
|
||||
extern void target_disable_btrace (struct btrace_target_info *btinfo);
|
||||
@ -2231,6 +2241,10 @@ extern enum btrace_error target_read_btrace (struct btrace_data *,
|
||||
struct btrace_target_info *,
|
||||
enum btrace_read_type);
|
||||
|
||||
/* See to_btrace_conf in struct target_ops. */
|
||||
extern const struct btrace_config *
|
||||
target_btrace_conf (const struct btrace_target_info *);
|
||||
|
||||
/* See to_stop_recording in struct target_ops. */
|
||||
extern void target_stop_recording (void);
|
||||
|
||||
|
@ -1,3 +1,15 @@
|
||||
2015-02-09 Markus Metzger <markus.t.metzger@intel.com>
|
||||
|
||||
* gdb.btrace/delta.exp: Update "info record" output.
|
||||
* gdb.btrace/enable.exp: Update "info record" output.
|
||||
* gdb.btrace/finish.exp: Update "info record" output.
|
||||
* gdb.btrace/instruction_history.exp: Update "info record" output.
|
||||
* gdb.btrace/next.exp: Update "info record" output.
|
||||
* gdb.btrace/nexti.exp: Update "info record" output.
|
||||
* gdb.btrace/step.exp: Update "info record" output.
|
||||
* gdb.btrace/stepi.exp: Update "info record" output.
|
||||
* gdb.btrace/nohist.exp: Update "info record" output.
|
||||
|
||||
2015-02-06 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
PR gdb/15678
|
||||
|
@ -39,6 +39,7 @@ gdb_test_no_output "record btrace"
|
||||
with_test_prefix "no trace" {
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 0 instructions in 0 functions for .*" \
|
||||
] "\r\n"]
|
||||
gdb_test "record instruction-history" "No trace\."
|
||||
@ -51,6 +52,7 @@ gdb_test "stepi"
|
||||
proc check_trace {} {
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 1 instructions in 1 functions for .*" \
|
||||
] "\r\n"]
|
||||
gdb_test "record instruction-history /f 1" \
|
||||
@ -71,6 +73,7 @@ with_test_prefix "twice" {
|
||||
gdb_test "reverse-stepi"
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 1 instructions in 1 functions for .*" \
|
||||
"Replay in progress\. At instruction 1\." \
|
||||
] "\r\n"] "reverse-stepi"
|
||||
@ -79,5 +82,6 @@ gdb_test "info record" [join [list \
|
||||
gdb_test "stepi"
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 1 instructions in 1 functions for .*" \
|
||||
] "\r\n"] "and back"
|
||||
|
@ -56,7 +56,9 @@ gdb_test "record btrace" "The process is already being recorded\\. Use \"record
|
||||
gdb_test "record full" "The process is already being recorded\\. Use \"record stop\" to stop recording first\\." "record full cannot be enabled"
|
||||
|
||||
# no trace recorded yet
|
||||
gdb_test "info record" "Active record target: record-btrace\r\nRecorded 0 instructions in 0 functions for thread 1.*\\." "info record without trace"
|
||||
gdb_test "info record" "Active record target: record-btrace\r
|
||||
.*\r
|
||||
Recorded 0 instructions in 0 functions for thread 1.*\\." "info record without trace"
|
||||
|
||||
# stop btrace record
|
||||
gdb_test "record stop" "Process record is stopped and all execution logs are deleted\\." "record stop"
|
||||
|
@ -37,6 +37,7 @@ gdb_test "next"
|
||||
proc check_replay_at { insn } {
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 40 instructions in 16 functions for .*" \
|
||||
"Replay in progress\. At instruction $insn\." \
|
||||
] "\r\n"]
|
||||
|
@ -50,7 +50,7 @@ gdb_continue_to_breakpoint "cont to $bp_location" ".*$srcfile2:$bp_location.*"
|
||||
set traced {}
|
||||
set testname "determine number of recorded instructions"
|
||||
gdb_test_multiple "info record" $testname {
|
||||
-re "Active record target: record-btrace\r\nRecorded \(\[0-9\]*\) instructions in \(\[0-9\]*\) functions for thread 1 .*\\.\r\n$gdb_prompt $" {
|
||||
-re "Active record target: record-btrace\r\n.*\r\nRecorded \(\[0-9\]*\) instructions in \(\[0-9\]*\) functions for thread 1 .*\\.\r\n$gdb_prompt $" {
|
||||
set traced $expect_out(1,string)
|
||||
pass $testname
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ gdb_test "next"
|
||||
proc check_replay_at { insn } {
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 40 instructions in 16 functions for .*" \
|
||||
"Replay in progress\. At instruction $insn\." \
|
||||
] "\r\n"]
|
||||
@ -55,6 +56,7 @@ with_test_prefix "reverse-next - 2" { check_replay_at 1 }
|
||||
gdb_test "next" ".*main\.3.*"
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 40 instructions in 16 functions for \[^\\\r\\\n\]*" \
|
||||
] "\r\n"] "next back"
|
||||
|
||||
|
@ -37,6 +37,7 @@ gdb_test "next"
|
||||
proc check_replay_at { insn } {
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 40 instructions in 16 functions for .*" \
|
||||
"Replay in progress\. At instruction $insn\." \
|
||||
] "\r\n"]
|
||||
@ -55,6 +56,7 @@ with_test_prefix "reverse-nexti - 1" { check_replay_at 1 }
|
||||
gdb_test "nexti" ".*main\.3.*" "next, 1.5"
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 40 instructions in 16 functions for \[^\\\r\\\n\]*" \
|
||||
] "\r\n"] "nexti back"
|
||||
|
||||
|
@ -33,6 +33,7 @@ if ![runto_main] {
|
||||
proc check_not_replaying {} {
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 0 instructions in 0 functions for \[^\\\r\\\n\]*" \
|
||||
] "\r\n"]
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ gdb_test "next"
|
||||
proc check_replay_at { insn } {
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 40 instructions in 16 functions for .*" \
|
||||
"Replay in progress\. At instruction $insn\." \
|
||||
] "\r\n"]
|
||||
@ -85,5 +86,6 @@ with_test_prefix "step to 39" { check_replay_at 39 }
|
||||
gdb_test "step" ".*main\.3.*"
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 40 instructions in 16 functions for \[^\\\r\\\n\]*" \
|
||||
] "\r\n"] "step to live"
|
||||
|
@ -35,6 +35,7 @@ if ![runto_main] {
|
||||
proc check_replay_at { insn } {
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 40 instructions in 16 functions for .*" \
|
||||
"Replay in progress\. At instruction $insn\." \
|
||||
] "\r\n"]
|
||||
@ -59,6 +60,7 @@ with_test_prefix "stepi to 40" { check_replay_at 40 }
|
||||
gdb_test "stepi" ".*main\.3.*"
|
||||
gdb_test "info record" [join [list \
|
||||
"Active record target: record-btrace" \
|
||||
"Recording format: .*" \
|
||||
"Recorded 40 instructions in 16 functions for \[^\\\r\\\n\]*" \
|
||||
] "\r\n"] "stepi to live"
|
||||
|
||||
|
@ -427,13 +427,14 @@ x86_linux_read_description (struct target_ops *ops)
|
||||
/* Enable branch tracing. */
|
||||
|
||||
static struct btrace_target_info *
|
||||
x86_linux_enable_btrace (struct target_ops *self, ptid_t ptid)
|
||||
x86_linux_enable_btrace (struct target_ops *self, ptid_t ptid,
|
||||
const struct btrace_config *conf)
|
||||
{
|
||||
struct btrace_target_info *tinfo;
|
||||
struct gdbarch *gdbarch;
|
||||
|
||||
errno = 0;
|
||||
tinfo = linux_enable_btrace (ptid);
|
||||
tinfo = linux_enable_btrace (ptid, conf);
|
||||
|
||||
if (tinfo == NULL)
|
||||
error (_("Could not enable branch tracing for %s: %s."),
|
||||
@ -476,6 +477,16 @@ x86_linux_read_btrace (struct target_ops *self,
|
||||
{
|
||||
return linux_read_btrace (data, btinfo, type);
|
||||
}
|
||||
|
||||
/* See to_btrace_conf in target.h. */
|
||||
|
||||
static const struct btrace_config *
|
||||
x86_linux_btrace_conf (struct target_ops *self,
|
||||
const struct btrace_target_info *btinfo)
|
||||
{
|
||||
return linux_btrace_conf (btinfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Helper for ps_get_thread_area. Sets BASE_ADDR to a pointer to
|
||||
@ -550,6 +561,7 @@ x86_linux_create_target (void)
|
||||
t->to_disable_btrace = x86_linux_disable_btrace;
|
||||
t->to_teardown_btrace = x86_linux_teardown_btrace;
|
||||
t->to_read_btrace = x86_linux_read_btrace;
|
||||
t->to_btrace_conf = x86_linux_btrace_conf;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user