record-btrace: add bts buffer size configuration option
authorMarkus Metzger <markus.t.metzger@intel.com>
Thu, 28 Nov 2013 15:39:12 +0000 (16:39 +0100)
committerMarkus Metzger <markus.t.metzger@intel.com>
Mon, 9 Feb 2015 08:42:28 +0000 (09:42 +0100)
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.

15 files changed:
gdb/ChangeLog
gdb/NEWS
gdb/btrace.c
gdb/common/btrace-common.h
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/features/btrace-conf.dtd
gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c
gdb/gdbserver/server.c
gdb/nat/linux-btrace.c
gdb/record-btrace.c
gdb/remote.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.btrace/buffer-size.exp [new file with mode: 0644]

index 57ad0612879b3492b073802093fc1952e9af519a..f3347e90a7e610546471b0d9eeceb1ab6c81e634 100644 (file)
@@ -1,3 +1,28 @@
+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.
+
 2015-02-09  Markus Metzger  <markus.t.metzger@intel.com>
 
        * Makefile.in (XMLFILES): Add btrace-conf.dtd.
index b3f8f60d1c2fa38d08de9bdd23e17569fef37c64..624f508ecf1a2ec5025b9e81c0fba5a2fdeb32b9 100644 (file)
--- 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.
index 8930c3cf6a90552ac0acfb4e422eb3f195978d1f..c7932bb33081348caaa435597636cacfdccafe6a 100644 (file)
@@ -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 }
 };
 
index 1df5821403a0ad5bd10cf2e89db37914a7b1cd7d..bb1510919912a37ccb2078ccfb66d5267e0e9bfc 100644 (file)
@@ -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.  */
index b4a9cbac7d40c3a4b09e4d73519aeb5312c8eee4..b8e1f7f392ef3b17261cc6e8f7258830880c7570 100644 (file)
@@ -1,3 +1,9 @@
+2015-02-09  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * 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  <markus.t.metzger@intel.com>
 
        * gdb.texinfo (Process Record and Replay): Describe the "record
index 411f0679f38fddc435f50d40f2d3daa34654880f..d1f22de979e4c7b1bfabfd1a692e03b041ab73c2 100644 (file)
@@ -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:
 <!ATTLIST btrace-conf  version CDATA   #FIXED "1.0">
 
 <!ELEMENT bts  EMPTY>
+<!ATTLIST bts  size    CDATA   #IMPLIED>
 @end smallexample
 
 @include agentexpr.texi
index ff54822d8b1e3864851c2140653bd48da7e3bc1a..588bb80dadf8e267b16a6fa8a712f5721ee07a6e 100644 (file)
@@ -8,3 +8,4 @@
 <!ATTLIST btrace-conf  version CDATA   #FIXED "1.0">
 
 <!ELEMENT bts  EMPTY>
+<!ATTLIST bts  size    CDATA   #IMPLIED>
index d489ebfa2141d4c06720ea91f5cd75210841b514..25f3adfef3c2cfbd04b6ecb14913b6f15a31a075 100644 (file)
@@ -1,3 +1,10 @@
+2015-02-09  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * 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  <markus.t.metzger@intel.com>
 
        * linux-low.c (linux_low_enable_btrace): Update parameters.
index b311d4b8386823741ce9a10192c8a533706a644f..eff940de1067d5d756a9215967e0c0101d02db88 100644 (file)
@@ -6041,7 +6041,9 @@ linux_low_btrace_conf (const struct btrace_target_info *tinfo,
          break;
 
        case BTRACE_FORMAT_BTS:
-         buffer_xml_printf (buffer, "<bts/>\n");
+         buffer_xml_printf (buffer, "<bts");
+         buffer_xml_printf (buffer, " size=\"0x%x\"", conf->bts.size);
+         buffer_xml_printf (buffer, " />\n");
          break;
        }
     }
index 17ee5e1e902d46b8a62180a111259a181f134526..156fcc8acc9530a46feba33a96510ca5094e89c5 100644 (file)
@@ -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;
 
index e827e9225dcbe76f1b40702d549ae3584d0012b8..62c0acf9db43d0693301dffb46e725a0e34542a5 100644 (file)
@@ -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;
     }
 
index 5c6ee434a558887db95d072a8854a2cee456c9b0..16bba88bf5363088d922c26d797b380c62b6cbfd 100644 (file)
@@ -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;
 }
index 0226f3f4a82845cb31f185bd8009b0c221ac57d0..3980aadd92c1877ab22488e7a6a31976ffb5f79d 100644 (file)
@@ -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;
index a211483b4509935d891efb089d37ebbec153efdb..f4c5ed0d9890f77565d0fd44d7b76e2a419e2ff6 100644 (file)
@@ -1,3 +1,7 @@
+2015-02-09  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * gdb.btrace/buffer-size: New.
+
 2015-02-09  Markus Metzger  <markus.t.metzger@intel.com>
 
        * 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 (file)
index 0000000..0381cc2
--- /dev/null
@@ -0,0 +1,57 @@
+# This testcase is part of GDB, the GNU debugger.
+#
+# Copyright 2013-2015 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <markus.t.metzger@intel.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+
+# 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"