[PATCH v2 5/7] btrace, gdbserver: remove the to_supports_btrace target method

Markus Metzger
2018-01-26T14:14:46Z

Remove the to_supports_btrace target method and instead rely on detecting errors
when trying to enable recording. This will also provide a suitable error
message explaining why recording is not possible.

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

gdb/
* btrace.c (btrace_enable): Remove target_supports_btrace call.
* nat/linux-btrace.c (perf_event_pt_event_type): Move.
(kernel_supports_bts, kernel_supports_pt, linux_supports_bts)
(linux_supports_pt, linux_supports_btrace): Remove.
(linux_enable_bts): Call cpu_supports_bts.
* nat/linux-btrace.h (linux_supports_btrace): Remove.
* remote.c (remote_supports_btrace): Remove.
(init_remote_ops): Remove remote_supports_btrace.
* target-delegates.c: Regenerated.
* target.c (target_supports_btrace): Remove.
* target.h (target_ops) <to_supports_btrace>: Remove
(target_supports_btrace): Remove.
* x86-linux-nat.c (x86_linux_create_target): Remove
linux_supports_btrace.

gdbserver/
* linux-low.c (linux_target_ops): Remove linux_supports_btrace.
* nto-low.c (nto_target_ops): Remove NULL for supports_btrace.
* spu-low.c (spu_target_ops): Likewise.
* win32-low.c (win32_target_ops): Likewise.
* server.c (supported_btrace_packets): Report packets unconditionally.
* target.h (target_ops) <supports_btrace>: Remove.
(target_supports_btrace): Remove.
---
gdb/btrace.c | 3 -
gdb/gdbserver/linux-low.c | 2 -
gdb/gdbserver/nto-low.c | 1 -
gdb/gdbserver/server.c | 25 +----
gdb/gdbserver/spu-low.c | 1 -
gdb/gdbserver/target.h | 7 --
gdb/gdbserver/win32-low.c | 1 -
gdb/nat/linux-btrace.c | 273 ++++------------------------------------------
gdb/nat/linux-btrace.h | 3 -
gdb/remote.c | 32 ------
gdb/target-delegates.c | 33 ------
gdb/target.c | 8 --
gdb/target.h | 7 --
gdb/x86-linux-nat.c | 1 -
14 files changed, 24 insertions(+), 373 deletions(-)

diff --git a/gdb/btrace.c b/gdb/btrace.c
index ffcf53a..2b031a4 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -1582,9 +1582,6 @@ btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
error (_("GDB does not support Intel Processor Trace."));
#endif /* !defined (HAVE_LIBIPT) */

- if (!target_supports_btrace (conf->format))
- error (_("Target does not support branch tracing."));
-
DEBUG ("enable thread %s (%s)", print_thread_id (tp),
target_pid_to_str (tp->ptid));

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 38142bb..c1ba961 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -7531,7 +7531,6 @@ static struct target_ops linux_target_ops = {
linux_qxfer_libraries_svr4,
linux_supports_agent,
#ifdef HAVE_LINUX_BTRACE
- linux_supports_btrace,
linux_enable_btrace,
linux_low_disable_btrace,
linux_low_read_btrace,
@@ -7541,7 +7540,6 @@ static struct target_ops linux_target_ops = {
NULL,
NULL,
NULL,
- NULL,
#endif
linux_supports_range_stepping,
linux_proc_pid_to_exec_file,
diff --git a/gdb/gdbserver/nto-low.c b/gdb/gdbserver/nto-low.c
index a570ca9..b68b811 100644
--- a/gdb/gdbserver/nto-low.c
+++ b/gdb/gdbserver/nto-low.c
@@ -991,7 +991,6 @@ static struct target_ops nto_target_ops = {
NULL, /* get_min_fast_tracepoint_insn_len */
NULL, /* qxfer_libraries_svr4 */
NULL, /* support_agent */
- NULL, /* support_btrace */
NULL, /* enable_btrace */
NULL, /* disable_btrace */
NULL, /* read_btrace */
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 5ce6281..cb02b58 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -2104,27 +2104,10 @@ crc32 (CORE_ADDR base, int len, unsigned int crc)
static void
supported_btrace_packets (char *buf)
{
- int btrace_supported = 0;
-
- if (target_supports_btrace (BTRACE_FORMAT_BTS))
- {
- strcat (buf, ";Qbtrace:bts+");
- strcat (buf, ";Qbtrace-conf:bts:size+");
-
- btrace_supported = 1;
- }
-
- if (target_supports_btrace (BTRACE_FORMAT_PT))
- {
- strcat (buf, ";Qbtrace:pt+");
- strcat (buf, ";Qbtrace-conf:pt:size+");
-
- btrace_supported = 1;
- }
-
- if (!btrace_supported)
- return;
-
+ strcat (buf, ";Qbtrace:bts+");
+ strcat (buf, ";Qbtrace-conf:bts:size+");
+ strcat (buf, ";Qbtrace:pt+");
+ strcat (buf, ";Qbtrace-conf:pt:size+");
strcat (buf, ";Qbtrace:off+");
strcat (buf, ";qXfer:btrace:read+");
strcat (buf, ";qXfer:btrace-conf:read+");
diff --git a/gdb/gdbserver/spu-low.c b/gdb/gdbserver/spu-low.c
index fd1f8d6..5b880d2 100644
--- a/gdb/gdbserver/spu-low.c
+++ b/gdb/gdbserver/spu-low.c
@@ -717,7 +717,6 @@ static struct target_ops spu_target_ops = {
NULL, /* get_min_fast_tracepoint_insn_len */
NULL, /* qxfer_libraries_svr4 */
NULL, /* support_agent */
- NULL, /* support_btrace */
NULL, /* enable_btrace */
NULL, /* disable_btrace */
NULL, /* read_btrace */
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 295e64d..dcefe1a 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -391,9 +391,6 @@ struct target_ops
/* Return true if target supports debugging agent. */
int (*supports_agent) (void);

- /* Check whether the target supports branch tracing. */
- int (*supports_btrace) (struct target_ops *, enum btrace_format);
-
/* Enable branch tracing for PTID based on CONF and allocate a branch trace
target information struct for reading and for disabling branch trace. */
struct btrace_target_info *(*enable_btrace)
@@ -623,10 +620,6 @@ int kill_inferior (int);
(the_target->supports_agent ? \
(*the_target->supports_agent) () : 0)

-#define target_supports_btrace(format) \
- (the_target->supports_btrace \
- ? (*the_target->supports_btrace) (the_target, format) : 0)
-
#define target_enable_btrace(ptid, conf) \
(*the_target->enable_btrace) (ptid, conf)

diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index b1d9b51..9f0c4e4 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -1842,7 +1842,6 @@ static struct target_ops win32_target_ops = {
NULL, /* get_min_fast_tracepoint_insn_len */
NULL, /* qxfer_libraries_svr4 */
NULL, /* support_agent */
- NULL, /* support_btrace */
NULL, /* enable_btrace */
NULL, /* disable_btrace */
NULL, /* read_btrace */
diff --git a/gdb/nat/linux-btrace.c b/gdb/nat/linux-btrace.c
index 2b37e41..23ad778 100644
--- a/gdb/nat/linux-btrace.c
+++ b/gdb/nat/linux-btrace.c
@@ -175,23 +175,6 @@ perf_event_read_all (struct perf_event_buffer *pev, gdb_byte **data,
pev->last_head = data_head;
}

-/* Determine the event type.
- Returns zero on success and fills in TYPE; returns -1 otherwise. */
-
-static int
-perf_event_pt_event_type (int *type)
-{
- gdb_file_up file
- = gdb_fopen_cloexec ("/sys/bus/event_source/devices/intel_pt/type", "r");
- if (file == nullptr)
- return -1;
-
- int found = fscanf (file.get (), "%d", type);
- if (found == 1)
- return 0;
- return -1;
-}
-
/* Try to determine the start address of the Linux kernel. */

static uint64_t
@@ -376,176 +359,6 @@ perf_event_read_bts (struct btrace_target_info* tinfo, const uint8_t *begin,
return btrace;
}

-/* Check whether the kernel supports BTS. */
-
-static int
-kernel_supports_bts (void)
-{
- struct perf_event_attr attr;
- pid_t child, pid;
- int status, file;
-
- errno = 0;
- child = fork ();
- switch (child)
- {
- case -1:
- warning (_("test bts: cannot fork: %s."), safe_strerror (errno));
- return 0;
-
- case 0:
- status = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
- if (status != 0)
- {
- warning (_("test bts: cannot PTRACE_TRACEME: %s."),
- safe_strerror (errno));
- _exit (1);
- }
-
- status = raise (SIGTRAP);
- if (status != 0)
- {
- warning (_("test bts: cannot raise SIGTRAP: %s."),
- safe_strerror (errno));
- _exit (1);
- }
-
- _exit (1);
-
- default:
- pid = waitpid (child, &status, 0);
- if (pid != child)
- {
- warning (_("test bts: bad pid %ld, error: %s."),
- (long) pid, safe_strerror (errno));
- return 0;
- }
-
- if (!WIFSTOPPED (status))
- {
- warning (_("test bts: expected stop. status: %d."),
- status);
- return 0;
- }
-
- memset (&attr, 0, sizeof (attr));
-
- attr.type = PERF_TYPE_HARDWARE;
- attr.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
- attr.sample_period = 1;
- attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_ADDR;
- attr.exclude_kernel = 1;
- attr.exclude_hv = 1;
- attr.exclude_idle = 1;
-
- file = syscall (SYS_perf_event_open, &attr, child, -1, -1, 0);
- if (file >= 0)
- close (file);
-
- kill (child, SIGKILL);
- ptrace (PTRACE_KILL, child, NULL, NULL);
-
- pid = waitpid (child, &status, 0);
- if (pid != child)
- {
- warning (_("test bts: bad pid %ld, error: %s."),
- (long) pid, safe_strerror (errno));
- if (!WIFSIGNALED (status))
- warning (_("test bts: expected killed. status: %d."),
- status);
- }
-
- return (file >= 0);
- }
-}
-
-/* Check whether the kernel supports Intel Processor Trace. */
-
-static int
-kernel_supports_pt (void)
-{
- struct perf_event_attr attr;
- pid_t child, pid;
- int status, file, type;
-
- errno = 0;
- child = fork ();
- switch (child)
- {
- case -1:
- warning (_("test pt: cannot fork: %s."), safe_strerror (errno));
- return 0;
-
- case 0:
- status = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
- if (status != 0)
- {
- warning (_("test pt: cannot PTRACE_TRACEME: %s."),
- safe_strerror (errno));
- _exit (1);
- }
-
- status = raise (SIGTRAP);
- if (status != 0)
- {
- warning (_("test pt: cannot raise SIGTRAP: %s."),
- safe_strerror (errno));
- _exit (1);
- }
-
- _exit (1);
-
- default:
- pid = waitpid (child, &status, 0);
- if (pid != child)
- {
- warning (_("test pt: bad pid %ld, error: %s."),
- (long) pid, safe_strerror (errno));
- return 0;
- }
-
- if (!WIFSTOPPED (status))
- {
- warning (_("test pt: expected stop. status: %d."),
- status);
- return 0;
- }
-
- status = perf_event_pt_event_type (&type);
- if (status != 0)
- file = -1;
- else
- {
- memset (&attr, 0, sizeof (attr));
-
- attr.size = sizeof (attr);
- attr.type = type;
- attr.exclude_kernel = 1;
- attr.exclude_hv = 1;
- attr.exclude_idle = 1;
-
- file = syscall (SYS_perf_event_open, &attr, child, -1, -1, 0);
- if (file >= 0)
- close (file);
- }
-
- kill (child, SIGKILL);
- ptrace (PTRACE_KILL, child, NULL, NULL);
-
- pid = waitpid (child, &status, 0);
- if (pid != child)
- {
- warning (_("test pt: bad pid %ld, error: %s."),
- (long) pid, safe_strerror (errno));
- if (!WIFSIGNALED (status))
- warning (_("test pt: expected killed. status: %d."),
- status);
- }
-
- return (file >= 0);
- }
-}
-
/* Check whether an Intel cpu supports BTS. */

static int
@@ -596,64 +409,6 @@ cpu_supports_bts (void)
}
}

-/* Check whether the linux target supports BTS. */
-
-static int
-linux_supports_bts (void)
-{
- static int cached;
-
- if (cached == 0)
- {
- if (!kernel_supports_bts ())
- cached = -1;
- else if (!cpu_supports_bts ())
- cached = -1;
- else
- cached = 1;
- }
-
- return cached > 0;
-}
-
-/* Check whether the linux target supports Intel Processor Trace. */
-
-static int
-linux_supports_pt (void)
-{
- static int cached;
-
- if (cached == 0)
- {
- if (!kernel_supports_pt ())
- cached = -1;
- else
- cached = 1;
- }
-
- return cached > 0;
-}
-
-/* See linux-btrace.h. */
-
-int
-linux_supports_btrace (struct target_ops *ops, enum btrace_format format)
-{
- switch (format)
- {
- case BTRACE_FORMAT_NONE:
- return 0;
-
- case BTRACE_FORMAT_BTS:
- return linux_supports_bts ();
-
- case BTRACE_FORMAT_PT:
- return linux_supports_pt ();
- }
-
- internal_error (__FILE__, __LINE__, _("Unknown branch trace format"));
-}
-
/* Enable branch tracing in BTS format. */

static struct btrace_target_info *
@@ -664,6 +419,9 @@ linux_enable_bts (ptid_t ptid, const struct btrace_config_bts *conf)
__u64 data_offset;
int pid, pg;

+ if (!cpu_supports_bts ())
+ error (_("GDB does not support BTS for the target cpu."));
+
gdb::unique_xmalloc_ptr<btrace_target_info> tinfo
(XCNEW (btrace_target_info));
tinfo->ptid = ptid;
@@ -770,6 +528,23 @@ linux_enable_bts (ptid_t ptid, const struct btrace_config_bts *conf)

#if defined (PERF_ATTR_SIZE_VER5)

+/* Determine the event type.
+ Returns zero on success and fills in TYPE; returns -1 otherwise. */
+
+static int
+perf_event_pt_event_type (int *type)
+{
+ gdb_file_up file =
+ gdb_fopen_cloexec ("/sys/bus/event_source/devices/intel_pt/type", "r");
+ if (file.get () == nullptr)
+ return -1;
+
+ int found = fscanf (file.get (), "%d", type);
+ if (found == 1)
+ return 0;
+ return -1;
+}
+
/* Enable branch tracing in Intel Processor Trace format. */

static struct btrace_target_info *
@@ -1146,14 +921,6 @@ linux_btrace_conf (const struct btrace_target_info *tinfo)

/* See linux-btrace.h. */

-int
-linux_supports_btrace (struct target_ops *ops, enum btrace_format format)
-{
- return 0;
-}
-
-/* See linux-btrace.h. */
-
struct btrace_target_info *
linux_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
{
diff --git a/gdb/nat/linux-btrace.h b/gdb/nat/linux-btrace.h
index 31a8d9e..1180301 100644
--- a/gdb/nat/linux-btrace.h
+++ b/gdb/nat/linux-btrace.h
@@ -103,9 +103,6 @@ struct btrace_target_info
#endif /* HAVE_LINUX_PERF_EVENT_H */
};

-/* See to_supports_btrace in target.h. */
-extern int linux_supports_btrace (struct target_ops *, enum btrace_format);
-
/* See to_enable_btrace in target.h. */
extern struct btrace_target_info *
linux_enable_btrace (ptid_t ptid, const struct btrace_config *conf);
diff --git a/gdb/remote.c b/gdb/remote.c
index 5ac84df..b12b690 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -13096,37 +13096,6 @@ remote_btrace_reset (void)
memset (&rs->btrace_config, 0, sizeof (rs->btrace_config));
}

-/* Check whether the target supports branch tracing. */
-
-static int
-remote_supports_btrace (struct target_ops *self, enum btrace_format format)
-{
- if (packet_support (PACKET_Qbtrace_off) != PACKET_ENABLE)
- return 0;
- if (packet_support (PACKET_qXfer_btrace) != PACKET_ENABLE)
- return 0;
-
- switch (format)
- {
- case BTRACE_FORMAT_NONE:
- return 0;
-
- case BTRACE_FORMAT_BTS:
- return (packet_support (PACKET_Qbtrace_bts) == PACKET_ENABLE);
-
- case BTRACE_FORMAT_PT:
- /* The trace is decoded on the host. Even if our target supports it,
- we still need to have libipt to decode the trace. */
-#if defined (HAVE_LIBIPT)
- return (packet_support (PACKET_Qbtrace_pt) == PACKET_ENABLE);
-#else /* !defined (HAVE_LIBIPT) */
- return 0;
-#endif /* !defined (HAVE_LIBIPT) */
- }
-
- internal_error (__FILE__, __LINE__, _("Unknown branch trace format"));
-}
-
/* Synchronize the configuration with the target. */

static void
@@ -13650,7 +13619,6 @@ Specify the serial device it is connected to\n\
remote_ops.to_traceframe_info = remote_traceframe_info;
remote_ops.to_use_agent = remote_use_agent;
remote_ops.to_can_use_agent = remote_can_use_agent;
- remote_ops.to_supports_btrace = remote_supports_btrace;
remote_ops.to_enable_btrace = remote_enable_btrace;
remote_ops.to_disable_btrace = remote_disable_btrace;
remote_ops.to_teardown_btrace = remote_teardown_btrace;
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index bc84791..3d90c06 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -3438,35 +3438,6 @@ debug_can_use_agent (struct target_ops *self)
return result;
}

-static int
-delegate_supports_btrace (struct target_ops *self, enum btrace_format arg1)
-{
- self = self->beneath;
- return self->to_supports_btrace (self, arg1);
-}
-
-static int
-tdefault_supports_btrace (struct target_ops *self, enum btrace_format arg1)
-{
- return 0;
-}
-
-static int
-debug_supports_btrace (struct target_ops *self, enum btrace_format arg1)
-{
- int result;
- fprintf_unfiltered (gdb_stdlog, "-> %s->to_supports_btrace (...)\n", debug_target.to_shortname);
- result = debug_target.to_supports_btrace (&debug_target, arg1);
- fprintf_unfiltered (gdb_stdlog, "<- %s->to_supports_btrace (", debug_target.to_shortname);
- target_debug_print_struct_target_ops_p (&debug_target);
- fputs_unfiltered (", ", gdb_stdlog);
- target_debug_print_enum_btrace_format (arg1);
- fputs_unfiltered (") = ", gdb_stdlog);
- target_debug_print_int (result);
- fputs_unfiltered ("\n", gdb_stdlog);
- return result;
-}
-
static struct btrace_target_info *
delegate_enable_btrace (struct target_ops *self, ptid_t arg1, const struct btrace_config *arg2)
{
@@ -4436,8 +4407,6 @@ install_delegators (struct target_ops *ops)
ops->to_use_agent = delegate_use_agent;
if (ops->to_can_use_agent == NULL)
ops->to_can_use_agent = delegate_can_use_agent;
- if (ops->to_supports_btrace == NULL)
- ops->to_supports_btrace = delegate_supports_btrace;
if (ops->to_enable_btrace == NULL)
ops->to_enable_btrace = delegate_enable_btrace;
if (ops->to_disable_btrace == NULL)
@@ -4624,7 +4593,6 @@ install_dummy_methods (struct target_ops *ops)
ops->to_traceframe_info = tdefault_traceframe_info;
ops->to_use_agent = tdefault_use_agent;
ops->to_can_use_agent = tdefault_can_use_agent;
- ops->to_supports_btrace = tdefault_supports_btrace;
ops->to_enable_btrace = tdefault_enable_btrace;
ops->to_disable_btrace = tdefault_disable_btrace;
ops->to_teardown_btrace = tdefault_teardown_btrace;
@@ -4784,7 +4752,6 @@ init_debug_target (struct target_ops *ops)
ops->to_traceframe_info = debug_traceframe_info;
ops->to_use_agent = debug_use_agent;
ops->to_can_use_agent = debug_can_use_agent;
- ops->to_supports_btrace = debug_supports_btrace;
ops->to_enable_btrace = debug_enable_btrace;
ops->to_disable_btrace = debug_disable_btrace;
ops->to_teardown_btrace = debug_teardown_btrace;
diff --git a/gdb/target.c b/gdb/target.c
index ce630f4..70d6842 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -3556,14 +3556,6 @@ target_ranged_break_num_registers (void)

/* See target.h. */

-int
-target_supports_btrace (enum btrace_format format)
-{
- return current_target.to_supports_btrace (&current_target, format);
-}
-
-/* See target.h. */
-
struct btrace_target_info *
target_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
{
diff --git a/gdb/target.h b/gdb/target.h
index 52361ba..1520e33 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1108,10 +1108,6 @@ struct target_ops
int (*to_can_use_agent) (struct target_ops *)
TARGET_DEFAULT_RETURN (0);

- /* Check whether the target supports branch tracing. */
- int (*to_supports_btrace) (struct target_ops *, enum btrace_format)
- TARGET_DEFAULT_RETURN (0);
-
/* Enable branch tracing for PTID using CONF configuration.
Return a branch trace target information struct for reading and for
disabling branch trace. */
@@ -2424,9 +2420,6 @@ extern void update_target_permissions (void);
\f
/* Imported from machine dependent code. */

-/* See to_supports_btrace in struct target_ops. */
-extern int target_supports_btrace (enum btrace_format);
-
/* See to_enable_btrace in struct target_ops. */
extern struct btrace_target_info *
target_enable_btrace (ptid_t ptid, const struct btrace_config *);
diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c
index 75f68de..a3bdaff 100644
--- a/gdb/x86-linux-nat.c
+++ b/gdb/x86-linux-nat.c
@@ -340,7 +340,6 @@ x86_linux_create_target (void)
t->to_read_description = x86_linux_read_description;

/* Add btrace methods. */
- t->to_supports_btrace = linux_supports_btrace;
t->to_enable_btrace = x86_linux_enable_btrace;
t->to_disable_btrace = x86_linux_disable_btrace;
t->to_teardown_btrace = x86_linux_teardown_btrace;
--
1.8.3.1