public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Markus Metzger <markus.t.metzger@intel.com>
To: gdb-patches@sourceware.org
Subject: [PATCH v2 3/7] btrace: prepare for throwing exceptions when enabling btrace
Date: Fri, 26 Jan 2018 14:14:00 -0000	[thread overview]
Message-ID: <1516976072-19282-4-git-send-email-markus.t.metzger@intel.com> (raw)
In-Reply-To: <1516976072-19282-1-git-send-email-markus.t.metzger@intel.com>

We indicate success or failure for enabling branch tracing via the pointer
return value.  Depending on the type of error, errno may provide additional
information.

Prepare for using exceptions with more descriptive error messages by using smart
pointers and objects with automatic destruction to hold intermediate results.

2018-01-26  Markus Metzger  <markus.t.metzger@intel.com>

gdb/
	* nat/linux-btrace.c: Include scoped_fd.h and scoped_mmap.h.
	(perf_event_pt_event_type): Use gdb_file_up.
	(linux_enable_bts, linux_enable_pt): Use gdb::unique_xmalloc_ptr,
	scoped_fd, and scoped_mmap.
---
 gdb/nat/linux-btrace.c | 118 +++++++++++++++++++++----------------------------
 1 file changed, 51 insertions(+), 67 deletions(-)

diff --git a/gdb/nat/linux-btrace.c b/gdb/nat/linux-btrace.c
index bbd0fe6..354094f 100644
--- a/gdb/nat/linux-btrace.c
+++ b/gdb/nat/linux-btrace.c
@@ -25,6 +25,8 @@
 #include "gdb_wait.h"
 #include "x86-cpuid.h"
 #include "filestuff.h"
+#include "common/scoped_fd.h"
+#include "common/scoped_mmap.h"
 
 #include <inttypes.h>
 
@@ -179,17 +181,12 @@ perf_event_read_all (struct perf_event_buffer *pev, gdb_byte **data,
 static int
 perf_event_pt_event_type (int *type)
 {
-  FILE *file;
-  int found;
-
-  file = fopen ("/sys/bus/event_source/devices/intel_pt/type", "r");
-  if (file == NULL)
+  gdb_file_up file
+    =  gdb_fopen_cloexec ("/sys/bus/event_source/devices/intel_pt/type", "r");
+  if (file == nullptr)
     return -1;
 
-  found = fscanf (file, "%d", type);
-
-  fclose (file);
-
+  int found = fscanf (file.get (), "%d", type);
   if (found == 1)
     return 0;
   return -1;
@@ -662,14 +659,13 @@ linux_supports_btrace (struct target_ops *ops, enum btrace_format format)
 static struct btrace_target_info *
 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;
   size_t size, pages;
   __u64 data_offset;
   int pid, pg;
 
-  tinfo = XCNEW (struct btrace_target_info);
+  gdb::unique_xmalloc_ptr<btrace_target_info> tinfo
+    (XCNEW (btrace_target_info));
   tinfo->ptid = ptid;
 
   tinfo->conf.format = BTRACE_FORMAT_BTS;
@@ -692,9 +688,9 @@ linux_enable_bts (ptid_t ptid, const struct btrace_config_bts *conf)
     pid = ptid_get_pid (ptid);
 
   errno = 0;
-  bts->file = syscall (SYS_perf_event_open, &bts->attr, pid, -1, -1, 0);
-  if (bts->file < 0)
-    goto err_out;
+  scoped_fd fd (syscall (SYS_perf_event_open, &bts->attr, pid, -1, -1, 0));
+  if (fd.get () < 0)
+    return nullptr;
 
   /* Convert the requested size in bytes to pages (rounding up).  */
   pages = ((size_t) conf->size / PAGE_SIZE
@@ -711,6 +707,7 @@ linux_enable_bts (ptid_t ptid, const struct btrace_config_bts *conf)
 
   /* We try to allocate the requested size.
      If that fails, try to get as much as we can.  */
+  scoped_mmap data;
   for (; pages > 0; pages >>= 1)
     {
       size_t length;
@@ -730,15 +727,16 @@ linux_enable_bts (ptid_t ptid, const struct btrace_config_bts *conf)
 	continue;
 
       /* The number of pages we request needs to be a power of two.  */
-      header = ((struct perf_event_mmap_page *)
-		mmap (NULL, length, PROT_READ, MAP_SHARED, bts->file, 0));
-      if (header != MAP_FAILED)
+      data.reset (nullptr, length, PROT_READ, MAP_SHARED, fd.get (), 0);
+      if (data.get () != MAP_FAILED)
 	break;
     }
 
   if (pages == 0)
-    goto err_file;
+    return nullptr;
 
+  struct perf_event_mmap_page *header = (struct perf_event_mmap_page *)
+    data.get ();
   data_offset = PAGE_SIZE;
 
 #if defined (PERF_ATTR_SIZE_VER5)
@@ -753,29 +751,21 @@ linux_enable_bts (ptid_t ptid, const struct btrace_config_bts *conf)
 
       /* Check for overflows.  */
       if ((__u64) size != data_size)
-	{
-	  munmap ((void *) header, size + PAGE_SIZE);
-	  goto err_file;
-	}
+	return nullptr;
     }
 #endif /* defined (PERF_ATTR_SIZE_VER5) */
 
-  bts->header = header;
-  bts->bts.mem = ((const uint8_t *) header) + data_offset;
   bts->bts.size = size;
   bts->bts.data_head = &header->data_head;
+  bts->bts.mem = (const uint8_t *) data.get () + data_offset;
   bts->bts.last_head = 0ull;
+  bts->header = header;
+  bts->file = fd.release ();
 
-  tinfo->conf.bts.size = (unsigned int) size;
-  return tinfo;
-
- err_file:
-  /* We were not able to allocate any buffer.  */
-  close (bts->file);
+  data.release ();
 
- err_out:
-  xfree (tinfo);
-  return NULL;
+  tinfo->conf.bts.size = (unsigned int) size;
+  return tinfo.release ();
 }
 
 #if defined (PERF_ATTR_SIZE_VER5)
@@ -785,10 +775,8 @@ linux_enable_bts (ptid_t ptid, const struct btrace_config_bts *conf)
 static struct btrace_target_info *
 linux_enable_pt (ptid_t ptid, const struct btrace_config_pt *conf)
 {
-  struct perf_event_mmap_page *header;
-  struct btrace_target_info *tinfo;
   struct btrace_tinfo_pt *pt;
-  size_t pages, size;
+  size_t pages;
   int pid, pg, errcode, type;
 
   if (conf->size == 0)
@@ -802,7 +790,8 @@ linux_enable_pt (ptid_t ptid, const struct btrace_config_pt *conf)
   if (pid == 0)
     pid = ptid_get_pid (ptid);
 
-  tinfo = XCNEW (struct btrace_target_info);
+  gdb::unique_xmalloc_ptr<btrace_target_info> tinfo
+    (XCNEW (btrace_target_info));
   tinfo->ptid = ptid;
 
   tinfo->conf.format = BTRACE_FORMAT_PT;
@@ -816,16 +805,18 @@ linux_enable_pt (ptid_t ptid, const struct btrace_config_pt *conf)
   pt->attr.exclude_idle = 1;
 
   errno = 0;
-  pt->file = syscall (SYS_perf_event_open, &pt->attr, pid, -1, -1, 0);
-  if (pt->file < 0)
-    goto err;
+  scoped_fd fd (syscall (SYS_perf_event_open, &pt->attr, pid, -1, -1, 0));
+  if (fd.get () < 0)
+    return nullptr;
 
   /* Allocate the configuration page. */
-  header = ((struct perf_event_mmap_page *)
-	    mmap (NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
-		  pt->file, 0));
-  if (header == MAP_FAILED)
-    goto err_file;
+  scoped_mmap data (nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
+		    fd.get (), 0);
+  if (data.get () == MAP_FAILED)
+    return nullptr;
+
+  struct perf_event_mmap_page *header = (struct perf_event_mmap_page *)
+    data.get ();
 
   header->aux_offset = header->data_offset + header->data_size;
 
@@ -844,6 +835,7 @@ linux_enable_pt (ptid_t ptid, const struct btrace_config_pt *conf)
 
   /* We try to allocate the requested size.
      If that fails, try to get as much as we can.  */
+  scoped_mmap aux;
   for (; pages > 0; pages >>= 1)
     {
       size_t length;
@@ -855,41 +847,33 @@ linux_enable_pt (ptid_t ptid, const struct btrace_config_pt *conf)
       if ((__u64) UINT_MAX < data_size)
 	continue;
 
-      size = (size_t) data_size;
+      length = (size_t) data_size;
 
       /* Check for overflows.  */
-      if ((__u64) size != data_size)
+      if ((__u64) length != data_size)
 	continue;
 
       header->aux_size = data_size;
-      length = size;
 
-      pt->pt.mem = ((const uint8_t *)
-		    mmap (NULL, length, PROT_READ, MAP_SHARED, pt->file,
-			  header->aux_offset));
-      if (pt->pt.mem != MAP_FAILED)
+      aux.reset (nullptr, length, PROT_READ, MAP_SHARED, fd.get (),
+		 header->aux_offset);
+      if (aux.get () != MAP_FAILED)
 	break;
     }
 
   if (pages == 0)
-    goto err_conf;
+    return nullptr;
 
-  pt->header = header;
-  pt->pt.size = size;
+  pt->pt.size = aux.size ();
+  pt->pt.mem = (const uint8_t *) aux.release ();
   pt->pt.data_head = &header->aux_head;
+  pt->header = header;
+  pt->file = fd.release ();
 
-  tinfo->conf.pt.size = (unsigned int) size;
-  return tinfo;
-
- err_conf:
-  munmap((void *) header, PAGE_SIZE);
-
- err_file:
-  close (pt->file);
+  data.release ();
 
- err:
-  xfree (tinfo);
-  return NULL;
+  tinfo->conf.pt.size = (unsigned int) pt->pt.size;
+  return tinfo.release ();
 }
 
 #else /* !defined (PERF_ATTR_SIZE_VER5) */
-- 
1.8.3.1

  parent reply	other threads:[~2018-01-26 14:14 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-26 14:14 [PATCH v2 0/7] improve btrace enable error reporting Markus Metzger
2018-01-26 14:14 ` [PATCH v2 1/7] common: add scoped_fd Markus Metzger
2018-02-13 16:48   ` Yao Qi
2018-02-13 17:28     ` Metzger, Markus T
2018-02-14 15:22       ` Yao Qi
2018-02-14 17:26         ` Metzger, Markus T
2018-02-19 15:28           ` Metzger, Markus T
2018-02-19 15:46             ` Eli Zaretskii
2018-02-20 10:12             ` Yao Qi
2018-02-20 10:46               ` Metzger, Markus T
2018-02-20 11:09                 ` Yao Qi
2018-02-20 13:16                   ` Metzger, Markus T
2018-01-26 14:14 ` [PATCH v2 5/7] btrace, gdbserver: remove the to_supports_btrace target method Markus Metzger
2018-02-24 16:51   ` Maciej W. Rozycki
2018-02-26 13:08     ` Metzger, Markus T
2018-02-26 19:30       ` Andreas Arnez
2018-02-26 21:58         ` Maciej W. Rozycki
2018-02-27 10:57           ` Metzger, Markus T
2018-02-27 15:32             ` Maciej W. Rozycki
2018-02-27 18:14               ` Metzger, Markus T
2018-02-28 10:29                 ` Maciej W. Rozycki
2018-02-28 11:09                   ` Maciej W. Rozycki
2018-02-28 11:24                     ` Metzger, Markus T
2018-02-28 12:53                       ` Metzger, Markus T
2018-02-28 15:55                         ` Maciej W. Rozycki
2018-02-28 16:08                         ` Eli Zaretskii
2018-02-28 12:00     ` Yao Qi
2018-02-28 16:27       ` Sergio Durigan Junior
2018-03-01 11:33         ` Metzger, Markus T
2018-03-01 19:27           ` Sergio Durigan Junior
2018-03-05 12:14             ` Yao Qi
2018-03-05 16:13               ` Sergio Durigan Junior
2018-03-06  9:02                 ` Yao Qi
2018-03-06 16:32                   ` Sergio Durigan Junior
2018-03-01 19:34           ` Maciej W. Rozycki
2018-01-26 14:14 ` [PATCH v2 6/7] btrace: improve enable error messages Markus Metzger
2018-01-26 14:14 ` [PATCH v2 2/7] common: add scoped_mmap Markus Metzger
2018-01-26 14:14 ` Markus Metzger [this message]
2018-01-26 14:14 ` [PATCH v2 4/7] btrace, gdbserver: use exceptions to convey btrace enable/disable errors Markus Metzger
2018-01-26 14:14 ` [PATCH v2 7/7] btrace: check perf_event_paranoid Markus Metzger
2018-02-06 16:28 ` [PATCH v2 0/7] improve btrace enable error reporting Pedro Alves
2018-02-07 10:41   ` Metzger, Markus T
2018-02-07 12:11     ` Pedro Alves
2018-02-08 10:40       ` Metzger, Markus T
2018-02-08 13:01         ` Pedro Alves
2018-02-08 13:49           ` Metzger, Markus T
2018-02-08 14:24             ` Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1516976072-19282-4-git-send-email-markus.t.metzger@intel.com \
    --to=markus.t.metzger@intel.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).