btrace, gdbserver: check btrace target pointers
authorMarkus Metzger <markus.t.metzger@intel.com>
Mon, 26 Feb 2018 10:59:43 +0000 (11:59 +0100)
committerMarkus Metzger <markus.t.metzger@intel.com>
Thu, 1 Mar 2018 11:25:24 +0000 (12:25 +0100)
By removing the supports_btrace gdbserver target method we relied on GDB
trying to enable branch tracing and failing on the attempt.

For targets that do not provide the btrace methods, however, an initial
request from GDB for the branch trace configuration to detect whether
gdbserver is already recording resulted in a protocol error.

Have the btrace target methods throw a "Target does not suppor branch
tracing" error and be prepared to handle exceptions in all functions that
call btrace target methods.  We therefore turn the target_* macros into
static inline functions.

Also remove the additional btrace target method checks that resulted in
the above protocol error.

Thanks to Maciej W. Rozycki <macro@mips.com> for reporting this.

gdbserver/
* target.h (target_enable_btrace, target_disable_btrace)
(target_read_btrace, target_read_btrace_conf): Turn macro into
inline function.  Throw error if target method is not defined.
* server.c (handle_qxfer_btrace, handle_qxfer_btrace_conf): Remove
check for btrace target method.  Be prepared to handle exceptions
from btrace target methods.

gdb/gdbserver/ChangeLog
gdb/gdbserver/server.c
gdb/gdbserver/target.h

index ac88a9d7785652205cc8f2b06ea8acd4cf72f90d..703bdfb1ba70702c38c992158909a3ed3f5d9946 100644 (file)
@@ -1,3 +1,12 @@
+2018-03-01  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * target.h (target_enable_btrace, target_disable_btrace)
+       (target_read_btrace, target_read_btrace_conf): Turn macro into
+       inline function.  Throw error if target method is not defined.
+       * server.c (handle_qxfer_btrace handle_qxfer_btrace_conf): Remove
+       check for btrace target method.  Be prepared to handle exceptions
+       from btrace target methods.
+
 2018-02-28  Sergio Durigan Junior  <sergiodj@redhat.com>
 
        * server.c (captured_main): Change order of error message printed
index f373d8a1e8a91b2308286f1c8f4020fc305b3475..ad327be0280343841ce80c03ee15e55d3e635e30 100644 (file)
@@ -1852,7 +1852,7 @@ handle_qxfer_btrace (const char *annex,
   enum btrace_read_type type;
   int result;
 
-  if (the_target->read_btrace == NULL || writebuf != NULL)
+  if (writebuf != NULL)
     return -2;
 
   if (ptid_equal (general_thread, null_ptid)
@@ -1891,12 +1891,21 @@ handle_qxfer_btrace (const char *annex,
     {
       buffer_free (&cache);
 
-      result = target_read_btrace (thread->btrace, &cache, type);
-      if (result != 0)
+      TRY
        {
-         memcpy (own_buf, cache.buffer, cache.used_size);
-         return -3;
+         result = target_read_btrace (thread->btrace, &cache, type);
+         if (result != 0)
+           memcpy (own_buf, cache.buffer, cache.used_size);
        }
+      CATCH (exception, RETURN_MASK_ERROR)
+       {
+         sprintf (own_buf, "E.%s", exception.message);
+         result = -1;
+       }
+      END_CATCH
+
+      if (result != 0)
+       return -3;
     }
   else if (offset > cache.used_size)
     {
@@ -1923,7 +1932,7 @@ handle_qxfer_btrace_conf (const char *annex,
   struct thread_info *thread;
   int result;
 
-  if (the_target->read_btrace_conf == NULL || writebuf != NULL)
+  if (writebuf != NULL)
     return -2;
 
   if (annex[0] != '\0')
@@ -1953,12 +1962,21 @@ handle_qxfer_btrace_conf (const char *annex,
     {
       buffer_free (&cache);
 
-      result = target_read_btrace_conf (thread->btrace, &cache);
-      if (result != 0)
+      TRY
        {
-         memcpy (own_buf, cache.buffer, cache.used_size);
-         return -3;
+         result = target_read_btrace_conf (thread->btrace, &cache);
+         if (result != 0)
+           memcpy (own_buf, cache.buffer, cache.used_size);
        }
+      CATCH (exception, RETURN_MASK_ERROR)
+       {
+         sprintf (own_buf, "E.%s", exception.message);
+         result = -1;
+       }
+      END_CATCH
+
+      if (result != 0)
+       return -3;
     }
   else if (offset > cache.used_size)
     {
index dcefe1a94b72c3121d33411c1a2e85dbc6666094..25accd2207508a2527db0c7ff46bdad8ebb6dac3 100644 (file)
@@ -620,17 +620,44 @@ int kill_inferior (int);
   (the_target->supports_agent ? \
    (*the_target->supports_agent) () : 0)
 
-#define target_enable_btrace(ptid, conf) \
-  (*the_target->enable_btrace) (ptid, conf)
+static inline struct btrace_target_info *
+target_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
+{
+  if (the_target->enable_btrace == nullptr)
+    error (_("Target does not support branch tracing."));
+
+  return (*the_target->enable_btrace) (ptid, conf);
+}
+
+static inline int
+target_disable_btrace (struct btrace_target_info *tinfo)
+{
+  if (the_target->disable_btrace == nullptr)
+    error (_("Target does not support branch tracing."));
 
-#define target_disable_btrace(tinfo) \
-  (*the_target->disable_btrace) (tinfo)
+  return (*the_target->disable_btrace) (tinfo);
+}
 
-#define target_read_btrace(tinfo, buffer, type)        \
-  (*the_target->read_btrace) (tinfo, buffer, type)
+static inline int
+target_read_btrace (struct btrace_target_info *tinfo,
+                   struct buffer *buffer,
+                   enum btrace_read_type type)
+{
+  if (the_target->read_btrace == nullptr)
+    error (_("Target does not support branch tracing."));
+
+  return (*the_target->read_btrace) (tinfo, buffer, type);
+}
+
+static inline int
+target_read_btrace_conf (struct btrace_target_info *tinfo,
+                        struct buffer *buffer)
+{
+  if (the_target->read_btrace_conf == nullptr)
+    error (_("Target does not support branch tracing."));
 
-#define target_read_btrace_conf(tinfo, buffer) \
-  (*the_target->read_btrace_conf) (tinfo, buffer)
+  return (*the_target->read_btrace_conf) (tinfo, buffer);
+}
 
 #define target_supports_range_stepping() \
   (the_target->supports_range_stepping ? \