aboutsummaryrefslogtreecommitdiff
path: root/gdb/nat
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2013-11-28 15:44:13 +0100
committerMarkus Metzger <markus.t.metzger@intel.com>2015-02-09 09:38:55 +0100
commitf4abbc168227003a4836dd1a5dd558f40be96372 (patch)
treef35162a46e74f2305cedf76f187f6f61d1e1e257 /gdb/nat
parentaadf7753fd4cc3d9eb1cd0c089fd7a483b58f59e (diff)
downloadgdb-f4abbc168227003a4836dd1a5dd558f40be96372.zip
gdb-f4abbc168227003a4836dd1a5dd558f40be96372.tar.gz
gdb-f4abbc168227003a4836dd1a5dd558f40be96372.tar.bz2
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 &current_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.
Diffstat (limited to 'gdb/nat')
-rw-r--r--gdb/nat/linux-btrace.c140
-rw-r--r--gdb/nat/linux-btrace.h35
2 files changed, 133 insertions, 42 deletions
diff --git a/gdb/nat/linux-btrace.c b/gdb/nat/linux-btrace.c
index 5b22661..e827e92 100644
--- a/gdb/nat/linux-btrace.c
+++ b/gdb/nat/linux-btrace.c
@@ -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;
- /* We sample from and to address. */
- tinfo->attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_ADDR;
+ 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;
- tinfo->attr.exclude_kernel = 1;
- tinfo->attr.exclude_hv = 1;
- tinfo->attr.exclude_idle = 1;
+ /* We sample from and to address. */
+ bts->attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_ADDR;
- 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;
+
+ 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. */
- return linux_read_bts (&btrace->variant.bts, tinfo, type);
+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 */
diff --git a/gdb/nat/linux-btrace.h b/gdb/nat/linux-btrace.h
index 602a571..12cdcde 100644
--- a/gdb/nat/linux-btrace.h
+++ b/gdb/nat/linux-btrace.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 */