aboutsummaryrefslogtreecommitdiff
path: root/gdb/nat/linux-btrace.c
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2013-11-28 16:39:12 +0100
committerMarkus Metzger <markus.t.metzger@intel.com>2015-02-09 09:42:28 +0100
commitd33501a51f46193387ff2d101752a9a878202f82 (patch)
treefbe786f422bb7045cc2c626314076e41ad3a346b /gdb/nat/linux-btrace.c
parentf4abbc168227003a4836dd1a5dd558f40be96372 (diff)
downloadgdb-d33501a51f46193387ff2d101752a9a878202f82.zip
gdb-d33501a51f46193387ff2d101752a9a878202f82.tar.gz
gdb-d33501a51f46193387ff2d101752a9a878202f82.tar.bz2
record-btrace: add bts buffer size configuration option
Allow the size of the branch trace ring buffer to be defined by the user. The specified buffer size will be used when BTS tracing is enabled for new threads. The obtained buffer size may differ from the requested size. The actual buffer size for the current thread is shown in the "info record" command. Bigger buffers mean longer traces, but also longer processing time. 2015-02-09 Markus Metzger <markus.t.metzger@intel.com> * btrace.c (parse_xml_btrace_conf_bts): Add size. (btrace_conf_bts_attributes): New. (btrace_conf_children): Add attributes. * common/btrace-common.h (btrace_config_bts): New. (btrace_config)<bts>: New. (btrace_config): Update comment. * nat/linux-btrace.c (linux_enable_btrace, linux_enable_bts): Use config. * features/btrace-conf.dtd: Increment version. Add size attribute to bts element. * record-btrace.c (set_record_btrace_bts_cmdlist, show_record_btrace_bts_cmdlist): New. (record_btrace_adjust_size, record_btrace_print_bts_conf, record_btrace_print_conf, cmd_set_record_btrace_bts, cmd_show_record_btrace_bts): New. (record_btrace_info): Call record_btrace_print_conf. (_initialize_record_btrace): Add commands. * remote.c: Add PACKET_Qbtrace_conf_bts_size enum. (remote_protocol_features): Add Qbtrace-conf:bts:size packet. (btrace_sync_conf): Synchronize bts size. (_initialize_remote): Add Qbtrace-conf:bts:size packet. * NEWS: Announce new commands and new packets. doc/ * gdb.texinfo (Branch Trace Configuration Format): Add size. (Process Record and Replay): Describe new set|show commands. (General Query Packets): Describe Qbtrace-conf:bts:size packet. testsuite/ * gdb.btrace/buffer-size: New. gdbserver/ * linux-low.c (linux_low_btrace_conf): Print size. * server.c (handle_btrace_conf_general_set): New. (hanle_general_set): Call handle_btrace_conf_general_set. (handle_query): Report Qbtrace-conf:bts:size as supported.
Diffstat (limited to 'gdb/nat/linux-btrace.c')
-rw-r--r--gdb/nat/linux-btrace.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/gdb/nat/linux-btrace.c b/gdb/nat/linux-btrace.c
index e827e92..62c0acf 100644
--- a/gdb/nat/linux-btrace.c
+++ b/gdb/nat/linux-btrace.c
@@ -398,11 +398,12 @@ linux_supports_btrace (struct target_ops *ops, enum btrace_format format)
/* Enable branch tracing in BTS format. */
static struct btrace_target_info *
-linux_enable_bts (ptid_t ptid, const struct btrace_config *conf)
+linux_enable_bts (ptid_t ptid, const struct btrace_config_bts *conf)
{
struct perf_event_mmap_page *header;
struct btrace_target_info *tinfo;
struct btrace_tinfo_bts *bts;
+ unsigned long long size, pages;
int pid, pg;
tinfo = xzalloc (sizeof (*tinfo));
@@ -433,14 +434,33 @@ linux_enable_bts (ptid_t ptid, const struct btrace_config *conf)
if (bts->file < 0)
goto err;
- /* We try to allocate as much buffer as we can get.
- We could allow the user to specify the size of the buffer, but then
- we'd leave this search for the maximum buffer size to him. */
- for (pg = 4; pg >= 0; --pg)
+ /* Convert the requested size in bytes to pages (rounding up). */
+ pages = (((unsigned long long) conf->size) + PAGE_SIZE - 1) / PAGE_SIZE;
+ /* We need at least one page. */
+ if (pages == 0)
+ pages = 1;
+
+ /* The buffer size can be requested in powers of two pages. Adjust PAGES
+ to the next power of two. */
+ for (pg = 0; pages != (1u << pg); ++pg)
+ if ((pages & (1u << pg)) != 0)
+ pages += (1u << pg);
+
+ /* We try to allocate the requested size.
+ If that fails, try to get as much as we can. */
+ for (; pages > 0; pages >>= 1)
{
+ size_t length;
+
+ size = pages * PAGE_SIZE;
+ length = size + PAGE_SIZE;
+
+ /* Check for overflows. */
+ if ((unsigned long long) length < size)
+ continue;
+
/* 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,
- bts->file, 0);
+ header = mmap (NULL, length, PROT_READ, MAP_SHARED, bts->file, 0);
if (header != MAP_FAILED)
break;
}
@@ -450,10 +470,11 @@ linux_enable_bts (ptid_t ptid, const struct btrace_config *conf)
bts->header = header;
bts->bts.mem = ((const uint8_t *) header) + PAGE_SIZE;
- bts->bts.size = (1 << pg) * PAGE_SIZE;
+ bts->bts.size = size;
bts->bts.data_head = &header->data_head;
bts->bts.last_head = 0;
+ tinfo->conf.bts.size = size;
return tinfo;
err_file:
@@ -479,7 +500,7 @@ linux_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
break;
case BTRACE_FORMAT_BTS:
- tinfo = linux_enable_bts (ptid, conf);
+ tinfo = linux_enable_bts (ptid, &conf->bts);
break;
}