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.
For remote debugging, gdbserver will now always advertise branch tracing related
packets. When talking to an older GDB, this will cause GDB to try to enable
branch tracing and gdbserver to report a suitable error message every time.
An older gdbserver will not advertise branch tracing related packets if the
one-time check failed, so a newer GDB with this patch will fail to enable branch
tracing at remote_enable_btrace() rather than at btrace_enable(). The error
message is the same in both cases so there should be no user-visible change.
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.
+2018-02-09 Markus Metzger <markus.t.metzger@intel.com>
+
+ * 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.
+
2018-02-09 Markus Metzger <markus.t.metzger@intel.com>
* nat/linux-btrace.c (linux_enable_btrace): Throw exception if enabling
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));
+2018-02-09 Markus Metzger <markus.t.metzger@intel.com>
+
+ * 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.
+
2018-02-09 Markus Metzger <markus.t.metzger@intel.com>
* server.c (handle_btrace_enable_bts, handle_btrace_enable_pt)
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,
NULL,
NULL,
NULL,
- NULL,
#endif
linux_supports_range_stepping,
linux_proc_pid_to_exec_file,
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 */
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+");
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 */
/* 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)
(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)
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 */
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
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
}
}
-/* 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 *
__u64 data_offset;
int pid, pg;
+ if (!cpu_supports_bts ())
+ error (_("BTS support has been disabled for the target cpu."));
+
gdb::unique_xmalloc_ptr<btrace_target_info> tinfo
(XCNEW (btrace_target_info));
tinfo->ptid = ptid;
#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 *
/* 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)
{
#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);
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
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;
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)
{
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)
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;
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;
/* See target.h. */
-int
-target_supports_btrace (enum btrace_format format)
-{
- return current_target.to_supports_btrace (¤t_target, format);
-}
-
-/* See target.h. */
-
struct btrace_target_info *
target_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
{
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. */
\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 *);
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;