@@ -12135,9 +12135,9 @@ catch_syscall_command_1 (char *arg, int from_tty,
struct gdbarch *gdbarch = get_current_arch ();
/* Checking if the feature if supported. */
- if (gdbarch_get_syscall_number_p (gdbarch) == 0)
+ if (!target_supports_syscall_catchpoint (gdbarch))
error (_("The feature 'catch syscall' is not supported on \
-this architecture yet."));
+this target yet."));
tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
@@ -1180,6 +1180,15 @@ inf_ttrace_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
return ptid_build (ptid_get_pid (inferior_ptid), lwp, 0);
}
+/* Implement the supports_syscall_catchpoint target_ops method. */
+
+static int
+inf_ttrace_supports_syscall_catchpoint (struct target_ops *self,
+ struct gdbarch *gdbarch)
+{
+ return 1;
+}
+
struct target_ops *
inf_ttrace_target (void)
@@ -1206,6 +1215,7 @@ inf_ttrace_target (void)
t->to_pid_to_str = inf_ttrace_pid_to_str;
t->to_xfer_partial = inf_ttrace_xfer_partial;
t->to_get_ada_task_ptid = inf_ttrace_get_ada_task_ptid;
+ t->to_supports_syscall_catchpoint = inf_ttrace_supports_syscall_catchpoint;
return t;
}
@@ -594,6 +594,15 @@ linux_child_set_syscall_catchpoint (struct target_ops *self,
return 0;
}
+/* Implement the supports_syscall_catchpoint target_ops method. */
+
+static int
+linux_child_supports_syscall_catchpoint (struct target_ops *ops,
+ struct gdbarch *gdbarch)
+{
+ return gdbarch_get_syscall_number_p (gdbarch);
+}
+
/* On GNU/Linux there are no real LWP's. The closest thing to LWP's
are processes sharing the same VM space. A multi-threaded process
is basically a group of such processes. However, such a grouping
@@ -4277,6 +4286,7 @@ linux_target_install_ops (struct target_ops *t)
t->to_insert_exec_catchpoint = linux_child_insert_exec_catchpoint;
t->to_remove_exec_catchpoint = linux_child_remove_exec_catchpoint;
t->to_set_syscall_catchpoint = linux_child_set_syscall_catchpoint;
+ t->to_supports_syscall_catchpoint = linux_child_supports_syscall_catchpoint;
t->to_pid_to_exec_file = linux_child_pid_to_exec_file;
t->to_post_startup_inferior = linux_child_post_startup_inferior;
t->to_post_attach = linux_child_post_attach;
@@ -1144,6 +1144,35 @@ debug_set_syscall_catchpoint (struct target_ops *self, int arg1, int arg2, int a
}
static int
+delegate_supports_syscall_catchpoint (struct target_ops *self, struct gdbarch *arg1)
+{
+ self = self->beneath;
+ return self->to_supports_syscall_catchpoint (self, arg1);
+}
+
+static int
+tdefault_supports_syscall_catchpoint (struct target_ops *self, struct gdbarch *arg1)
+{
+ return 0;
+}
+
+static int
+debug_supports_syscall_catchpoint (struct target_ops *self, struct gdbarch *arg1)
+{
+ int result;
+ fprintf_unfiltered (gdb_stdlog, "-> %s->to_supports_syscall_catchpoint (...)\n", debug_target.to_shortname);
+ result = debug_target.to_supports_syscall_catchpoint (&debug_target, arg1);
+ fprintf_unfiltered (gdb_stdlog, "<- %s->to_supports_syscall_catchpoint (", debug_target.to_shortname);
+ target_debug_print_struct_target_ops_p (&debug_target);
+ fputs_unfiltered (", ", gdb_stdlog);
+ target_debug_print_struct_gdbarch_p (arg1);
+ fputs_unfiltered (") = ", gdb_stdlog);
+ target_debug_print_int (result);
+ fputs_unfiltered ("\n", gdb_stdlog);
+ return result;
+}
+
+static int
delegate_has_exited (struct target_ops *self, int arg1, int arg2, int *arg3)
{
self = self->beneath;
@@ -3849,6 +3878,8 @@ install_delegators (struct target_ops *ops)
ops->to_remove_exec_catchpoint = delegate_remove_exec_catchpoint;
if (ops->to_set_syscall_catchpoint == NULL)
ops->to_set_syscall_catchpoint = delegate_set_syscall_catchpoint;
+ if (ops->to_supports_syscall_catchpoint == NULL)
+ ops->to_supports_syscall_catchpoint = delegate_supports_syscall_catchpoint;
if (ops->to_has_exited == NULL)
ops->to_has_exited = delegate_has_exited;
if (ops->to_mourn_inferior == NULL)
@@ -4091,6 +4122,7 @@ install_dummy_methods (struct target_ops *ops)
ops->to_insert_exec_catchpoint = tdefault_insert_exec_catchpoint;
ops->to_remove_exec_catchpoint = tdefault_remove_exec_catchpoint;
ops->to_set_syscall_catchpoint = tdefault_set_syscall_catchpoint;
+ ops->to_supports_syscall_catchpoint = tdefault_supports_syscall_catchpoint;
ops->to_has_exited = tdefault_has_exited;
ops->to_mourn_inferior = default_mourn_inferior;
ops->to_can_run = tdefault_can_run;
@@ -4235,6 +4267,7 @@ init_debug_target (struct target_ops *ops)
ops->to_insert_exec_catchpoint = debug_insert_exec_catchpoint;
ops->to_remove_exec_catchpoint = debug_remove_exec_catchpoint;
ops->to_set_syscall_catchpoint = debug_set_syscall_catchpoint;
+ ops->to_supports_syscall_catchpoint = debug_supports_syscall_catchpoint;
ops->to_has_exited = debug_has_exited;
ops->to_mourn_inferior = debug_mourn_inferior;
ops->to_can_run = debug_can_run;
@@ -541,6 +541,9 @@ struct target_ops
int (*to_set_syscall_catchpoint) (struct target_ops *,
int, int, int, int, int *)
TARGET_DEFAULT_RETURN (1);
+ int (*to_supports_syscall_catchpoint) (struct target_ops *,
+ struct gdbarch *)
+ TARGET_DEFAULT_RETURN (0);
int (*to_has_exited) (struct target_ops *, int, int, int *)
TARGET_DEFAULT_RETURN (0);
void (*to_mourn_inferior) (struct target_ops *)
@@ -1523,6 +1526,12 @@ int target_follow_fork (int follow_child, int detach_fork);
pid, needed, any_count, \
table_size, table)
+/* Return true if GDBARCH on current target supports syscall catchpoint,
+ otherwise, return false. */
+
+#define target_supports_syscall_catchpoint(gdbarch) \
+ (*current_target.to_supports_syscall_catchpoint) (¤t_target, gdbarch)
+
/* Returns TRUE if PID has exited. And, also sets EXIT_STATUS to the
exit code of PID, if any. */
From: Yao Qi <yao.qi@linaro.org> Nowadays, "catch syscall" is supported on linux-nat target of different gdbarch and inf-ttrace target. However, in breakpoint.c:catch_syscall_command_1, we have this check /* Checking if the feature if supported. */ if (gdbarch_get_syscall_number_p (gdbarch) == 0) error (_("The feature 'catch syscall' is not supported on \ this architecture yet.")); On one hand, gdbarch method get_syscall_number isn't installed on any HP-UX targets. That means users will get such error message even syscall catchpoint is supported on HP-UX. On the other hand, on linux remote target (with GDBserver), "catch syscall" isn't supported (PR 13585), but no error is emitted: (gdb) target remote :1234 Remote debugging using :1234 Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done. 0x00007ffff7ddb2d0 in ?? () from /lib64/ld-linux-x86-64.so.2 (gdb) catch syscall close Catchpoint 1 (syscall 'close' [3]) The fix in this patch is to add a new target method supports_syscall_catchpoint, so that we can have different implementations on different targets. On inf-ttrace, we can simply return one, while on linux-child, gdbarch_get_syscall_number_p is called. With this patch applied, on linux remote target, it becomes: (gdb) target remote :1234 Remote debugging using :1234 Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done. 0x00007ffff7ddb2d0 in ?? () from /lib64/ld-linux-x86-64.so.2 (gdb) catch syscall close The feature 'catch syscall' is not supported on this target yet. which looks more reasonable to me. However, this patch causes some regressions in catch-syscall.exp, catch syscall nonsense_syscall^M The feature 'catch syscall' is not supported on this target yet.^M (gdb) FAIL: gdb.base/catch-syscall.exp: catch syscall to a nonsense syscall is prohibited because syscall catchpoint isn't supported on exec target. I can move these tests to the place where inferior is created, before I go too far, I'd like to hear what do you think of this. gdb: 2015-02-27 Yao Qi <yao.qi@linaro.org> * breakpoint.c (catch_syscall_command_1): Call target_supports_syscall_catchpoint instead of gdbarch_get_syscall_number_p. * inf-ttrace.c (inf_ttrace_supports_syscall_catchpoint): New function. (inf_ttrace_target): Install field to_supports_syscall_catchpoint. * linux-nat.c (linux_child_supports_syscall_catchpoint): New function. (linux_target_install_ops): Install field to_supports_syscall_catchpoint. * target-delegates.c: Regenerated. * target.h (struct target_ops) <to_supports_syscall_catchpoint>: New field. (target_supports_syscall_catchpoint): New macro. --- gdb/breakpoint.c | 4 ++-- gdb/inf-ttrace.c | 10 ++++++++++ gdb/linux-nat.c | 10 ++++++++++ gdb/target-delegates.c | 33 +++++++++++++++++++++++++++++++++ gdb/target.h | 9 +++++++++ 5 files changed, 64 insertions(+), 2 deletions(-)