This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v3a 05/15] record-btrace: add bts buffer size configuration option


Changes to the previous v3 in the series:

  Fixed a bug where the requested size in bytes might overflow when
  the buffer size is set high enough (e.g. unlimited), resulting in
  a zero-sized buffer.

  I simplified the buffer size computation and added an overflow check.

---

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-04  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.
---
 gdb/NEWS                                 |  14 ++++
 gdb/btrace.c                             |  14 +++-
 gdb/common/btrace-common.h               |  15 +++-
 gdb/doc/gdb.texinfo                      |  78 ++++++++++++++++++--
 gdb/features/btrace-conf.dtd             |   1 +
 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/gdb.btrace/buffer-size.exp |  57 +++++++++++++++
 11 files changed, 421 insertions(+), 21 deletions(-)
 create mode 100644 gdb/testsuite/gdb.btrace/buffer-size.exp

diff --git a/gdb/NEWS b/gdb/NEWS
index 08d604d..4844f33 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -14,6 +14,12 @@
 * The command 'thread apply all' can now support new option '-ascending'
   to call its specified command for all threads in ascending order.
 
+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.
+
 * New commands
 
 record btrace bts
@@ -25,6 +31,14 @@ record bts
 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 8930c3c..c7932bb 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 7d30952..69e223c 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/gdb.texinfo b/gdb/doc/gdb.texinfo
index 3b35f3f..7cc5619 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -6529,6 +6529,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
@@ -6555,9 +6579,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
@@ -35709,6 +35749,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{-}
@@ -35966,6 +36011,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::
@@ -36405,6 +36453,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
@@ -38933,7 +38993,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}.
@@ -38945,6 +39014,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
diff --git a/gdb/features/btrace-conf.dtd b/gdb/features/btrace-conf.dtd
index e9cb2ef..907816c 100644
--- a/gdb/features/btrace-conf.dtd
+++ b/gdb/features/btrace-conf.dtd
@@ -8,3 +8,4 @@
 <!ATTLIST btrace-conf	version	CDATA	#FIXED "1.0">
 
 <!ELEMENT bts	EMPTY>
+<!ATTLIST bts	size	CDATA	#IMPLIED>
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 3d07e5d..62be7aa 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -6028,7 +6028,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;
 	}
     }
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 17ee5e1..156fcc8 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 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;
     }
 
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 9fa1182..957da8d 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.  */
 
@@ -269,6 +277,71 @@ record_btrace_close (struct target_ops *self)
     btrace_teardown (tp);
 }
 
+/* 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
@@ -289,8 +362,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);
 
@@ -2056,6 +2128,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.  */
@@ -2099,9 +2190,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 d2eaa10..b78b848 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
@@ -12279,6 +12312,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/gdb.btrace/buffer-size.exp b/gdb/testsuite/gdb.btrace/buffer-size.exp
new file mode 100644
index 0000000..0e0be1b
--- /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-2014 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: Intel\\\(R\\\) 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: Intel\\\(R\\\) 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"
-- 
1.8.3.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]