From d33501a51f46193387ff2d101752a9a878202f82 Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Thu, 28 Nov 2013 16:39:12 +0100 Subject: [PATCH] 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 * 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): 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. --- gdb/ChangeLog | 25 +++++ gdb/NEWS | 14 +++ gdb/btrace.c | 14 ++- gdb/common/btrace-common.h | 15 ++- gdb/doc/ChangeLog | 6 ++ gdb/doc/gdb.texinfo | 78 ++++++++++++++- gdb/features/btrace-conf.dtd | 1 + gdb/gdbserver/ChangeLog | 7 ++ gdb/gdbserver/linux-low.c | 4 +- gdb/gdbserver/server.c | 60 +++++++++++- gdb/nat/linux-btrace.c | 39 ++++++-- gdb/record-btrace.c | 120 ++++++++++++++++++++++- gdb/remote.c | 40 +++++++- gdb/testsuite/ChangeLog | 4 + gdb/testsuite/gdb.btrace/buffer-size.exp | 57 +++++++++++ 15 files changed, 463 insertions(+), 21 deletions(-) create mode 100644 gdb/testsuite/gdb.btrace/buffer-size.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 57ad0612879..f3347e90a7e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,28 @@ +2015-02-09 Markus Metzger + + * 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): 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. + 2015-02-09 Markus Metzger * Makefile.in (XMLFILES): Add btrace-conf.dtd. diff --git a/gdb/NEWS b/gdb/NEWS index b3f8f60d1c2..624f508ecf1 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -41,6 +41,12 @@ maint set symbol-cache-size maint show symbol-cache-size Control the size of the symbol cache. +set|show record btrace bts buffer-size + Set and show the size of the ring buffer used for branch tracing in + BTS format. + The obtained size may differ from the requested size. Use "info + record" to see the obtained buffer size. + * The command 'thread apply all' can now support new option '-ascending' to call its specified command for all threads in ascending order. @@ -54,6 +60,14 @@ maint show symbol-cache-size qXfer:btrace-conf:read Return the branch trace configuration for the current thread. +Qbtrace-conf:bts:size + Set the requested ring buffer size for branch tracing in BTS format. + +* The info record command now shows the recording format and the + branch tracing configuration for the current thread when using + the btrace record target. + For the BTS format, it shows the ring buffer size. + *** Changes in GDB 7.9 * GDB now supports hardware watchpoints on x86 GNU Hurd. diff --git a/gdb/btrace.c b/gdb/btrace.c index 8930c3cf6a9..c7932bb3308 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -1127,13 +1127,25 @@ parse_xml_btrace_conf_bts (struct gdb_xml_parser *parser, void *user_data, VEC (gdb_xml_value_s) *attributes) { struct btrace_config *conf; + struct gdb_xml_value *size; conf = user_data; conf->format = BTRACE_FORMAT_BTS; + conf->bts.size = 0; + + size = xml_find_attribute (attributes, "size"); + if (size != NULL) + conf->bts.size = (unsigned int) * (ULONGEST *) size->value; } +static const struct gdb_xml_attribute btrace_conf_bts_attributes[] = { + { "size", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL }, + { NULL, GDB_XML_AF_NONE, NULL, NULL } +}; + static const struct gdb_xml_element btrace_conf_children[] = { - { "bts", NULL, NULL, GDB_XML_EF_OPTIONAL, parse_xml_btrace_conf_bts, NULL }, + { "bts", btrace_conf_bts_attributes, NULL, GDB_XML_EF_OPTIONAL, + parse_xml_btrace_conf_bts, NULL }, { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } }; diff --git a/gdb/common/btrace-common.h b/gdb/common/btrace-common.h index 1df5821403a..bb151091991 100644 --- a/gdb/common/btrace-common.h +++ b/gdb/common/btrace-common.h @@ -61,15 +61,28 @@ enum btrace_format BTRACE_FORMAT_BTS }; +/* A BTS configuration. */ + +struct btrace_config_bts +{ + /* The size of the branch trace buffer in bytes. */ + unsigned int size; +}; + /* A branch tracing configuration. This describes the requested configuration as well as the actually - obtained configuration. */ + obtained configuration. + We describe the configuration for all different formats so we can + easily switch between formats. */ struct btrace_config { /* The branch tracing format. */ enum btrace_format format; + + /* The BTS format configuration. */ + struct btrace_config_bts bts; }; /* Branch trace in BTS format. */ diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index b4a9cbac7d4..b8e1f7f392e 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,9 @@ +2015-02-09 Markus Metzger + + * 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. + 2015-02-09 Markus Metzger * gdb.texinfo (Process Record and Replay): Describe the "record diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 411f0679f38..d1f22de979e 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -6561,6 +6561,30 @@ position. @item show record btrace replay-memory-access Show the current setting of @code{replay-memory-access}. +@kindex set record btrace bts +@item set record btrace bts buffer-size @var{size} +@itemx set record btrace bts buffer-size unlimited +Set the requested ring buffer size for branch tracing in @acronym{BTS} +format. Default is 64KB. + +If @var{size} is a positive number, then @value{GDBN} will try to +allocate a buffer of at least @var{size} bytes for each new thread +that uses the btrace recording method and the @acronym{BTS} format. +The actually obtained buffer size may differ from the requested +@var{size}. Use the @code{info record} command to see the actual +buffer size for each thread that uses the btrace recording method and +the @acronym{BTS} format. + +If @var{limit} is @code{unlimited} or zero, @value{GDBN} will try to +allocate a buffer of 4MB. + +Bigger buffers mean longer traces. On the other hand, @value{GDBN} will +also need longer to process the branch trace data before it can be used. + +@item show record btrace bts buffer-size @var{size} +Show the current setting of the requested ring buffer size for branch +tracing in @acronym{BTS} format. + @kindex info record @item info record Show various statistics about the recording depending on the recording @@ -6587,9 +6611,25 @@ 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 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. +For the @code{btrace} recording method, it shows: + +@itemize @bullet +@item +Recording format. +@item +Number of instructions that have been recorded. +@item +Number of blocks of sequential control-flow formed by the recorded +instructions. +@item +Whether in record mode or replay mode. +@end itemize + +For the @code{bts} recording format, it also shows: +@itemize @bullet +@item +Size of the perf ring buffer. +@end itemize @end table @kindex record delete @@ -35826,6 +35866,11 @@ These are the currently defined stub features and their properties: @tab @samp{-} @tab Yes +@item @samp{Qbtrace-conf:bts:size} +@tab Yes +@tab @samp{-} +@tab Yes + @item @samp{QNonStop} @tab No @tab @samp{-} @@ -36083,6 +36128,9 @@ The remote stub understands the @samp{Qbtrace:off} packet. @item Qbtrace:bts The remote stub understands the @samp{Qbtrace:bts} packet. +@item Qbtrace-conf:bts:size +The remote stub understands the @samp{Qbtrace-conf:bts:size} packet. + @end table @item qSymbol:: @@ -36522,6 +36570,18 @@ Branch tracing has been disabled. A badly formed request or an error was encountered. @end table +@item Qbtrace-conf:bts:size=@var{value} +Set the requested ring buffer size for new threads that use the +btrace recording method in bts format. + +Reply: +@table @samp +@item OK +The ring buffer size has been set. +@item E.errtext +A badly formed request or an error was encountered. +@end table + @end table @node Architecture-Specific Protocol Details @@ -39050,7 +39110,16 @@ 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. +settings for that format. The following information is described: + +@table @code +@item bts +This thread uses the @dfn{Branch Trace Store} (@acronym{BTS}) format. +@table @code +@item size +The size of the @acronym{BTS} ring buffer in bytes. +@end table +@end table @value{GDBN} must be linked with the Expat library to support XML branch trace configuration discovery. @xref{Expat}. @@ -39062,6 +39131,7 @@ The formal DTD for the branch trace configuration format is given below: + @end smallexample @include agentexpr.texi diff --git a/gdb/features/btrace-conf.dtd b/gdb/features/btrace-conf.dtd index ff54822d8b1..588bb80dadf 100644 --- a/gdb/features/btrace-conf.dtd +++ b/gdb/features/btrace-conf.dtd @@ -8,3 +8,4 @@ + diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index d489ebfa214..25f3adfef3c 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,10 @@ +2015-02-09 Markus Metzger + + * 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. + 2015-02-09 Markus Metzger * linux-low.c (linux_low_enable_btrace): Update parameters. diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index b311d4b8386..eff940de106 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -6041,7 +6041,9 @@ linux_low_btrace_conf (const struct btrace_target_info *tinfo, break; case BTRACE_FORMAT_BTS: - buffer_xml_printf (buffer, "\n"); + buffer_xml_printf (buffer, "bts.size); + buffer_xml_printf (buffer, " />\n"); break; } } diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 17ee5e1e902..156fcc8acc9 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -463,6 +463,58 @@ handle_btrace_general_set (char *own_buf) return 1; } +/* Handle the "Qbtrace-conf" packet. */ + +static int +handle_btrace_conf_general_set (char *own_buf) +{ + struct thread_info *thread; + char *op; + + if (strncmp ("Qbtrace-conf:", own_buf, strlen ("Qbtrace-conf:")) != 0) + return 0; + + op = own_buf + strlen ("Qbtrace-conf:"); + + if (ptid_equal (general_thread, null_ptid) + || ptid_equal (general_thread, minus_one_ptid)) + { + strcpy (own_buf, "E.Must select a single thread."); + return -1; + } + + thread = find_thread_ptid (general_thread); + if (thread == NULL) + { + strcpy (own_buf, "E.No such thread."); + return -1; + } + + if (strncmp (op, "bts:size=", strlen ("bts:size=")) == 0) + { + unsigned long size; + char *endp = NULL; + + errno = 0; + size = strtoul (op + strlen ("bts:size="), &endp, 16); + if (endp == NULL || *endp != 0 || errno != 0 || size > UINT_MAX) + { + strcpy (own_buf, "E.Bad size value."); + return -1; + } + + current_btrace_conf.bts.size = (unsigned int) size; + } + else + { + strcpy (own_buf, "E.Bad Qbtrace configuration option."); + return -1; + } + + write_ok (own_buf); + return 1; +} + /* Handle all of the extended 'Q' packets. */ static void @@ -622,6 +674,9 @@ handle_general_set (char *own_buf) if (handle_btrace_general_set (own_buf)) return; + if (handle_btrace_conf_general_set (own_buf)) + return; + /* Otherwise we didn't know what packet it was. Say we didn't understand it. */ own_buf[0] = 0; @@ -1761,7 +1816,10 @@ static void supported_btrace_packets (char *buf) { if (target_supports_btrace (BTRACE_FORMAT_BTS)) - strcat (buf, ";Qbtrace:bts+"); + { + strcat (buf, ";Qbtrace:bts+"); + strcat (buf, ";Qbtrace-conf:bts:size+"); + } else return; diff --git a/gdb/nat/linux-btrace.c b/gdb/nat/linux-btrace.c index e827e9225dc..62c0acf9db4 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; } diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 5c6ee434a55..16bba88bf53 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -76,6 +76,14 @@ static struct btrace_config record_btrace_conf; /* Command list for "record btrace". */ static struct cmd_list_element *record_btrace_cmdlist; +/* Command lists for "set/show record btrace". */ +static struct cmd_list_element *set_record_btrace_cmdlist; +static struct cmd_list_element *show_record_btrace_cmdlist; + +/* Command lists for "set/show record btrace bts". */ +static struct cmd_list_element *set_record_btrace_bts_cmdlist; +static struct cmd_list_element *show_record_btrace_bts_cmdlist; + /* Print a record-btrace debug message. Use do ... while (0) to avoid ambiguities when used in if statements. */ @@ -285,6 +293,71 @@ record_btrace_async (struct target_ops *ops, ops->beneath->to_async (ops->beneath, callback, context); } +/* Adjusts the size and returns a human readable size suffix. */ + +static const char * +record_btrace_adjust_size (unsigned int *size) +{ + unsigned int sz; + + sz = *size; + + if ((sz & ((1u << 30) - 1)) == 0) + { + *size = sz >> 30; + return "GB"; + } + else if ((sz & ((1u << 20) - 1)) == 0) + { + *size = sz >> 20; + return "MB"; + } + else if ((sz & ((1u << 10) - 1)) == 0) + { + *size = sz >> 10; + return "kB"; + } + else + return ""; +} + +/* Print a BTS configuration. */ + +static void +record_btrace_print_bts_conf (const struct btrace_config_bts *conf) +{ + const char *suffix; + unsigned int size; + + size = conf->size; + if (size > 0) + { + suffix = record_btrace_adjust_size (&size); + printf_unfiltered (_("Buffer size: %u%s.\n"), size, suffix); + } +} + +/* Print a branch tracing configuration. */ + +static void +record_btrace_print_conf (const struct btrace_config *conf) +{ + printf_unfiltered (_("Recording format: %s.\n"), + btrace_format_string (conf->format)); + + switch (conf->format) + { + case BTRACE_FORMAT_NONE: + return; + + case BTRACE_FORMAT_BTS: + record_btrace_print_bts_conf (&conf->bts); + return; + } + + internal_error (__FILE__, __LINE__, _("Unkown branch trace format.")); +} + /* The to_info_record method of target record-btrace. */ static void @@ -305,8 +378,7 @@ record_btrace_info (struct target_ops *self) conf = btrace_conf (btinfo); if (conf != NULL) - printf_unfiltered (_("Recording format: %s.\n"), - btrace_format_string (conf->format)); + record_btrace_print_conf (conf); btrace_fetch (tp); @@ -2073,6 +2145,25 @@ cmd_show_replay_memory_access (struct ui_file *file, int from_tty, replay_memory_access); } +/* The "set record btrace bts" command. */ + +static void +cmd_set_record_btrace_bts (char *args, int from_tty) +{ + printf_unfiltered (_("\"set record btrace bts\" must be followed " + "by an apporpriate subcommand.\n")); + help_list (set_record_btrace_bts_cmdlist, "set record btrace bts ", + all_commands, gdb_stdout); +} + +/* The "show record btrace bts" command. */ + +static void +cmd_show_record_btrace_bts (char *args, int from_tty) +{ + cmd_show_list (show_record_btrace_bts_cmdlist, from_tty, ""); +} + void _initialize_record_btrace (void); /* Initialize btrace commands. */ @@ -2116,9 +2207,34 @@ replay."), &set_record_btrace_cmdlist, &show_record_btrace_cmdlist); + add_prefix_cmd ("bts", class_support, cmd_set_record_btrace_bts, + _("Set record btrace bts options"), + &set_record_btrace_bts_cmdlist, + "set record btrace bts ", 0, &set_record_btrace_cmdlist); + + add_prefix_cmd ("bts", class_support, cmd_show_record_btrace_bts, + _("Show record btrace bts options"), + &show_record_btrace_bts_cmdlist, + "show record btrace bts ", 0, &show_record_btrace_cmdlist); + + add_setshow_uinteger_cmd ("buffer-size", no_class, + &record_btrace_conf.bts.size, + _("Set the record/replay bts buffer size."), + _("Show the record/replay bts buffer size."), _("\ +When starting recording request a trace buffer of this size. \ +The actual buffer size may differ from the requested size. \ +Use \"info record\" to see the actual buffer size.\n\n\ +Bigger buffers allow longer recording but also take more time to process \ +the recorded execution trace.\n\n\ +The trace buffer size may not be changed while recording."), NULL, NULL, + &set_record_btrace_bts_cmdlist, + &show_record_btrace_bts_cmdlist); + init_record_btrace_ops (); add_target (&record_btrace_ops); bfcache = htab_create_alloc (50, bfcache_hash, bfcache_eq, NULL, xcalloc, xfree); + + record_btrace_conf.bts.size = 64 * 1024; } diff --git a/gdb/remote.c b/gdb/remote.c index 0226f3f4a82..3980aadd92c 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -1335,6 +1335,9 @@ enum { /* Support for the qXfer:btrace-conf:read packet. */ PACKET_qXfer_btrace_conf, + /* Support for the Qbtrace-conf:bts:size packet. */ + PACKET_Qbtrace_conf_bts_size, + PACKET_MAX }; @@ -4020,7 +4023,9 @@ static const struct protocol_feature remote_protocol_features[] = { { "qXfer:btrace:read", PACKET_DISABLE, remote_supported_packet, PACKET_qXfer_btrace }, { "qXfer:btrace-conf:read", PACKET_DISABLE, remote_supported_packet, - PACKET_qXfer_btrace_conf } + PACKET_qXfer_btrace_conf }, + { "Qbtrace-conf:bts:size", PACKET_DISABLE, remote_supported_packet, + PACKET_Qbtrace_conf_bts_size } }; static char *remote_support_xml; @@ -11378,7 +11383,35 @@ remote_supports_btrace (struct target_ops *self, enum btrace_format format) static void btrace_sync_conf (const struct btrace_config *conf) { - /* Nothing to do for now. */ + struct packet_config *packet; + struct remote_state *rs; + char *buf, *pos, *endbuf; + + rs = get_remote_state (); + buf = rs->buf; + endbuf = buf + get_remote_packet_size (); + + packet = &remote_protocol_packets[PACKET_Qbtrace_conf_bts_size]; + if (packet_config_support (packet) == PACKET_ENABLE + && conf->bts.size != rs->btrace_config.bts.size) + { + pos = buf; + pos += xsnprintf (pos, endbuf - pos, "%s=0x%x", packet->name, + conf->bts.size); + + putpkt (buf); + getpkt (&buf, &rs->buf_size, 0); + + if (packet_ok (buf, packet) == PACKET_ERROR) + { + if (buf[0] == 'E' && buf[1] == '.') + error (_("Failed to configure the BTS buffer size: %s"), buf + 2); + else + error (_("Failed to configure the BTS buffer size.")); + } + + rs->btrace_config.bts.size = conf->bts.size; + } } /* Read the current thread's btrace configuration from the target and @@ -12287,6 +12320,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_conf], "qXfer:btrace-conf", "read-btrace-conf", 0); + add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_conf_bts_size], + "Qbtrace-conf:bts:size", "btrace-conf-bts-size", 0); + /* Assert that we've registered commands for all packet configs. */ { int i; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index a211483b450..f4c5ed0d989 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-02-09 Markus Metzger + + * gdb.btrace/buffer-size: New. + 2015-02-09 Markus Metzger * gdb.btrace/delta.exp: Update "info record" output. diff --git a/gdb/testsuite/gdb.btrace/buffer-size.exp b/gdb/testsuite/gdb.btrace/buffer-size.exp new file mode 100644 index 00000000000..0381cc231fc --- /dev/null +++ b/gdb/testsuite/gdb.btrace/buffer-size.exp @@ -0,0 +1,57 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2013-2015 Free Software Foundation, Inc. +# +# Contributed by Intel Corp. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# check for btrace support +if { [skip_btrace_tests] } { return -1 } + +# start inferior +standard_testfile record_goto.c +if [prepare_for_testing $testfile.exp $testfile $srcfile] { + return -1 +} + +if ![runto_main] { + return -1 +} + +gdb_test_no_output "set record btrace bts buffer-size 1" +gdb_test "show record btrace bts buffer-size" "The record/replay bts buffer size is 1\.\r" "bts buffer size before recording" + +gdb_test_no_output "record btrace bts" +gdb_test "show record btrace bts buffer-size" "The record/replay bts buffer size is 1\.\r" "bts buffer size while recording" +gdb_test "info record" [join [list \ + "Active record target: record-btrace" \ + "Recording format: Branch Trace Store\." \ + "Buffer size: 4kB\." \ + "Recorded 0 instructions in 0 functions for \[^\\\r\\\n\]*" \ + ] "\r\n"] "info record with small bts buffer" +gdb_test "record stop" ".*" "stop recording with small bts buffer" + +gdb_test_no_output "set record btrace bts buffer-size 0" +gdb_test "show record btrace bts buffer-size" "The record/replay bts buffer size is unlimited\.\r" "unlimited bts buffer size before recording" + +gdb_test_no_output "record btrace bts" +gdb_test "show record btrace bts buffer-size" "The record/replay bts buffer size is unlimited\.\r" "unlimited bts buffer size while recording" +gdb_test "info record" [join [list \ + "Active record target: record-btrace" \ + "Recording format: Branch Trace Store\." \ + "Buffer size: .*\." \ + "Recorded 0 instructions in 0 functions for \[^\\\r\\\n\]*" \ + ] "\r\n"] "info record with unlimited bts buffer" +gdb_test "record stop" ".*" "stop recording with unlimited bts buffer" -- 2.30.2