From patchwork Fri May 20 02:55:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 12405 Received: (qmail 42745 invoked by alias); 20 May 2016 02:56:15 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 42726 invoked by uid 89); 20 May 2016 02:56:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.2 spammy=sk:catch_s X-HELO: layla.krisman.be Received: from layla.krisman.be (HELO layla.krisman.be) (176.31.208.35) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 20 May 2016 02:56:08 +0000 Received: from [127.0.0.1] (localhost [127.0.0.1]) with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA1:128) (envelope-from ) id 1b3aAp-0002O2-CD; Fri, 20 May 2016 04:28:24 +0200 From: Gabriel Krisman Bertazi To: gdb-patches@sourceware.org Cc: palves@redhat.com, sergiodj@redhat.com, dje@google.com, Gabriel Krisman Bertazi Subject: [PATCH v6 2/5] Add support to catch groups of syscalls. Date: Thu, 19 May 2016 23:55:45 -0300 Message-Id: <1463712948-9068-2-git-send-email-gabriel@krisman.be> In-Reply-To: <1463712948-9068-1-git-send-email-gabriel@krisman.be> References: <87shxd1mx2.fsf@oberon.home> <1463712948-9068-1-git-send-email-gabriel@krisman.be> X-IsSubscribed: yes This implements the catchpoint side. While parsing 'catch syscall' arguments, we verify if the argument is a syscall group and expand it to a list of syscalls that are part of that group. gdb/ * 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. --- gdb/break-catch-syscall.c | 93 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 9 deletions(-) diff --git a/gdb/break-catch-syscall.c b/gdb/break-catch-syscall.c index dbebdda..c564b8f 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; }