diff options
author | Gabriel Krisman Bertazi <gabriel@krisman.be> | 2016-07-23 18:38:24 -0300 |
---|---|---|
committer | Gabriel Krisman Bertazi <gabriel@krisman.be> | 2016-07-23 18:38:24 -0300 |
commit | e34879080d8935792ef3942efa5f25b4c3169b5a (patch) | |
tree | daab863d91a6bb66ab2c10f1f4ef50b52dab66ea /gdb/break-catch-syscall.c | |
parent | 49ecef2a7da2ee9df4ae675f99b70518fbf1bb23 (diff) | |
download | gdb-e34879080d8935792ef3942efa5f25b4c3169b5a.zip gdb-e34879080d8935792ef3942efa5f25b4c3169b5a.tar.gz gdb-e34879080d8935792ef3942efa5f25b4c3169b5a.tar.bz2 |
Implement catch syscall group
Implement support to add catchpoints for a group of related syscalls
using the syntax:
(gdb) catch syscall group:<group>
or
(gdb) catch syscall g:<group>
Several groups are predefined in the xml files for all architectures
supported by GDB over Linux. They are based on the groups defined by
strace.
gdb/
* xml-syscall.c (get_syscalls_by_group): New.
(get_syscall_group_names): New.
(struct syscall_group_desc): New structure to store group data.
(struct syscalls_info): Include field to store the group list.
(sysinfo_free_syscall_group_desc): New.
(free_syscalls_info): Free group list.
(syscall_group_create_syscall_group_desc): New.
(syscall_group_add_syscall): New.
(syscall_create_syscall_desc): Add syscall to its groups.
(syscall_start_syscall): Load group attribute.
(syscall_group_get_group_by_name): New.
(xml_list_syscalls_by_group): New.
(xml_list_of_groups): New.
* xml-syscall.h (get_syscalls_by_group): Export function
to retrieve a list of syscalls filtered by the group name.
(get_syscall_group_names): Export function to retrieve the list
of syscall groups.
* break-catch-syscall.c (catch_syscall_split_args): Verify if
argument is a syscall group and expand it to a list of syscalls
when creating catchpoints.
(catch_syscall_completer): Add word completion for system call
groups.
* configure.ac: Include dependency for xsltproc when building
in maintainer-mode.
* break-catch-syscall.c (_initialize_breakpoint): Update catch
syscall command documentation.
* NEWS: Include section about catching groups of syscalls.
* configure: Regenerate.
* data-directory/Makefile.in: Generate syscall xml when building
in maintainer mode.
* syscalls/gdb-syscalls.dtd: Include group attribute to the
syscall element.
* syscalls/apply-defaults.xsl: New.
* syscalls/linux-defaults.xml.in: New.
* syscalls/aarch64-linux.xml: Rename to aarch64-linux.xml.in.
* syscalls/amd64-linux.xml: Rename to amd64-linux.xml.in.
* syscalls/arm-linux.xml: Rename to arm-linux.xml.in.
* syscalls/bfin-linux.xml: Rename to bfin-linux.xml.in.
* syscalls/i386-linux.xml: Rename to i386-linux.xml.in.
* syscalls/mips-n32-linux.xml: Rename to mips-n32-linux.xml.in.
* syscalls/mips-n64-linux.xml: Rename to mips-n64-linux.xml.in.
* syscalls/mips-o32-linux.xml: Rename to mips-o32-linux.xml.in.
* syscalls/ppc-linux.xml: Rename to ppc-linux.xml.in.
* syscalls/ppc64-linux.xml: Rename to ppc64-linux.xml.in.
* syscalls/s390-linux.xml: Rename to s390-linux.xml.in.
* syscalls/s390x-linux.xml: Rename to s390x-linux.xml.in.
* syscalls/sparc-linux.xml: Rename to sparc-linux.xml.in.
* syscalls/sparc64-linux.xml: Rename to sparc64-linux.xml.in.
* syscalls/aarch64-linux.xml: Regenerate.
* syscalls/amd64-linux.xml: Regenerate.
* syscalls/arm-linux.xml: Regenerate.
* syscalls/i386-linux.xml: Regenerate.
* syscalls/mips-n32-linux.xml: Regenerate.
* syscalls/mips-n64-linux.xml: Regenerate.
* syscalls/mips-o32-linux.xml: Regenerate.
* syscalls/ppc-linux.xml: Regenerate.
* syscalls/ppc64-linux.xml: Regenerate.
* syscalls/s390-linux.xml: Regenerate.
* syscalls/s390x-linux.xml: Regenerate.
* syscalls/sparc-linux.xml: Regenerate.
* syscalls/sparc64-linux.xml: Regenerate.
gdb/testsuite/
* gdb.base/catch-syscall.exp (do_syscall_tests): Add call
to test_catch_syscall_group.
(test_catch_syscall_group): New.
gdb/doc/
* gdb.texinfo (Set Catchpoints): Add 'group' argument to catch
syscall.
Diffstat (limited to 'gdb/break-catch-syscall.c')
-rw-r--r-- | gdb/break-catch-syscall.c | 103 |
1 files changed, 89 insertions, 14 deletions
diff --git a/gdb/break-catch-syscall.c b/gdb/break-catch-syscall.c index dbebdda..602aba4 100644 --- a/gdb/break-catch-syscall.c +++ b/gdb/break-catch-syscall.c @@ -464,10 +464,38 @@ catch_syscall_split_args (char *arg) cur_name[i] = '\0'; arg += i; - /* Check if the user provided a syscall name or a number. */ + /* Check if the user provided a syscall name, group, or a number. */ syscall_number = (int) strtol (cur_name, &endptr, 0); if (*endptr == '\0') - get_syscall_by_number (gdbarch, syscall_number, &s); + { + get_syscall_by_number (gdbarch, syscall_number, &s); + VEC_safe_push (int, result, s.number); + } + else if (startswith (cur_name, "g:") + || startswith (cur_name, "group:")) + { + /* We have a syscall group. Let's expand it into a syscall + list before inserting. */ + struct syscall *syscall_list; + const char *group_name; + + /* Skip over "g:" and "group:" prefix strings. */ + group_name = strchr (cur_name, ':') + 1; + + syscall_list = get_syscalls_by_group (gdbarch, group_name); + + if (syscall_list == NULL) + error (_("Unknown syscall group '%s'."), group_name); + + for (i = 0; syscall_list[i].name != NULL; i++) + { + /* Insert each syscall that are part of the group. No + need to check if it is valid. */ + VEC_safe_push (int, result, syscall_list[i].number); + } + + xfree (syscall_list); + } else { /* We have a name. Let's check if it's valid and convert it @@ -479,10 +507,10 @@ catch_syscall_split_args (char *arg) because GDB cannot do anything useful if there's no syscall number to be caught. */ error (_("Unknown syscall name '%s'."), cur_name); - } - /* Ok, it's valid. */ - VEC_safe_push (int, result, s.number); + /* Ok, it's valid. */ + VEC_safe_push (int, result, s.number); + } } discard_cleanups (cleanup); @@ -597,11 +625,58 @@ static VEC (char_ptr) * catch_syscall_completer (struct cmd_list_element *cmd, const char *text, const char *word) { - const char **list = get_syscall_names (get_current_arch ()); - VEC (char_ptr) *retlist - = (list == NULL) ? NULL : complete_on_enum (list, word, word); + struct gdbarch *gdbarch = get_current_arch (); + struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); + VEC (char_ptr) *group_retlist = NULL; + VEC (char_ptr) *syscall_retlist = NULL; + VEC (char_ptr) *retlist = NULL; + const char **group_list = NULL; + const char **syscall_list = NULL; + const char *prefix; + int i; + + /* Completion considers ':' to be a word separator, so we use this to + verify whether the previous word was a group prefix. If so, we + build the completion list using group names only. */ + for (prefix = word; prefix != text && prefix[-1] != ' '; prefix--) + ; + + if (startswith (prefix, "g:") || startswith (prefix, "group:")) + { + /* Perform completion inside 'group:' namespace only. */ + group_list = get_syscall_group_names (gdbarch); + retlist = (group_list == NULL + ? NULL : complete_on_enum (group_list, word, word)); + } + else + { + /* Complete with both, syscall names and groups. */ + syscall_list = get_syscall_names (gdbarch); + group_list = get_syscall_group_names (gdbarch); + + /* Append "group:" prefix to syscall groups. */ + for (i = 0; group_list[i] != NULL; i++) + { + char *prefixed_group = xstrprintf ("group:%s", group_list[i]); + + group_list[i] = prefixed_group; + make_cleanup (xfree, prefixed_group); + } + + syscall_retlist = ((syscall_list == NULL) + ? NULL : complete_on_enum (syscall_list, word, word)); + group_retlist = ((group_list == NULL) + ? NULL : complete_on_enum (group_list, word, word)); + + retlist = VEC_merge (char_ptr, syscall_retlist, group_retlist); + } + + VEC_free (char_ptr, syscall_retlist); + VEC_free (char_ptr, group_retlist); + xfree (syscall_list); + xfree (group_list); + do_cleanups (cleanups); - xfree (list); return retlist; } @@ -649,11 +724,11 @@ _initialize_break_catch_syscall (void) catch_syscall_inferior_data_cleanup); add_catch_command ("syscall", _("\ -Catch system calls by their names and/or numbers.\n\ -Arguments say which system calls to catch. If no arguments\n\ -are given, every system call will be caught.\n\ -Arguments, if given, should be one or more system call names\n\ -(if your system supports that), or system call numbers."), +Catch system calls by their names, groups and/or numbers.\n\ +Arguments say which system calls to catch. If no arguments are given,\n\ +every system call will be caught. Arguments, if given, should be one\n\ +or more system call names (if your system supports that), system call\n\ +groups or system call numbers."), catch_syscall_command_1, catch_syscall_completer, CATCH_PERMANENT, |