From patchwork Wed Oct 16 23:27:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 35069 Received: (qmail 98208 invoked by alias); 16 Oct 2019 23:28:20 -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 98141 invoked by uid 89); 16 Oct 2019 23:28:19 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=UD:kind, Regular, FILES X-HELO: mail-wm1-f50.google.com Received: from mail-wm1-f50.google.com (HELO mail-wm1-f50.google.com) (209.85.128.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 16 Oct 2019 23:28:16 +0000 Received: by mail-wm1-f50.google.com with SMTP id 5so549226wmg.0 for ; Wed, 16 Oct 2019 16:28:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=IRPSwJcILgwmqwpxmJx3uFWZIif9LuEnIFkIGPYcCjg=; b=cdIqCdjxY3q4bjtLWGeXPu0pd7X4ah/tMXuLiW2/WqItTd3Bc3M0F50zHXbT1LBFGg 0ZvnfFh0waofLqsrql9wSbCI4NlpNydoPiLejYgnW1xFeTuF5wSSdSqHv5NaoZ7zZL0t sqhfbVaYH56X6jqQV/lVBntpJvcJsr52B9vnTT42qI8umXsozopW8mezaMEXYPR248m+ KwEhrXAN4a5D4OEoU2W78hCyXL8DW8kU/fCjEPhhBLHg3yuf9XYOas13NPfRDd8UnNWe kxaQN/o1BDSH/H5aJYFsNL/vUpIdA2XGZg6NBdO5/LwPnm1REHBoq1oMzM225g9LStNS qCPg== Return-Path: Received: from localhost (host86-128-12-122.range86-128.btcentralplus.com. [86.128.12.122]) by smtp.gmail.com with ESMTPSA id f3sm289709wrq.53.2019.10.16.16.28.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 16 Oct 2019 16:28:13 -0700 (PDT) From: Andrew Burgess To: gdb-patches Cc: Andrew Burgess Subject: [PATCHv3 4/9] gdb: Introduce symbol_search_spec Date: Thu, 17 Oct 2019 00:27:59 +0100 Message-Id: In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes Introduce a new structure to wrap up the parameters needed for search_symbols. We already pass a lot of parameters to search_symbols and a later commit is going to add more. As part of this conversion the list of filenames has been converted to a std::vector. There should be no user visible changes after this commit. gdb/ChangeLog: * python/python.c (gdbpy_rbreak): Convert to using search_symbols_spec. * symtab.c (file_matches): Convert return type to bool, change file list to std::vector. (search_symbols): Update to use search_symbols_spec, and take account of the changes to file_matches. (symtab_symbol_info): Convert to using search_symbols_spec. (rbreak_command): Likewise. (search_module_symbols): Likewise. * symtab.h (struct search_symbols_spec): New struct. (search_symbols): Update parameters. Change-Id: I488ab292a892d9e9e84775c632c5f198b6ad3710 --- gdb/ChangeLog | 14 +++++++ gdb/python/python.c | 48 +++++++++++------------ gdb/symtab.c | 107 +++++++++++++++++++++------------------------------- gdb/symtab.h | 52 ++++++++++++++++++++++--- 4 files changed, 127 insertions(+), 94 deletions(-) diff --git a/gdb/python/python.c b/gdb/python/python.c index ddf0e72d26f..05ad038865a 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -645,19 +645,6 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) static PyObject * gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw) { - /* A simple type to ensure clean up of a vector of allocated strings - when a C interface demands a const char *array[] type - interface. */ - struct symtab_list_type - { - ~symtab_list_type () - { - for (const char *elem: vec) - xfree ((void *) elem); - } - std::vector vec; - }; - char *regex = NULL; std::vector symbols; unsigned long count = 0; @@ -667,7 +654,6 @@ gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw) unsigned int throttle = 0; static const char *keywords[] = {"regex","minsyms", "throttle", "symtabs", NULL}; - symtab_list_type symtab_paths; if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!IO", keywords, ®ex, &PyBool_Type, @@ -684,6 +670,26 @@ gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw) minsyms_p = cmp; } + /* A wrapper around search_symbols_spec in order to call free the + strings held in the filenames vector. */ + struct python_rbreak_search_symbols_spec + { + search_symbols_spec spec; + + python_rbreak_search_symbols_spec (const char *regex) + : spec (FUNCTIONS_DOMAIN, regex) + { /* Nothing. */ } + + ~python_rbreak_search_symbols_spec () + { + for (const char *elem: spec.filenames) + xfree ((void *) elem); + } + }; + + /* The search spec. */ + python_rbreak_search_symbols_spec spec (regex); + /* The "symtabs" keyword is any Python iterable object that returns a gdb.Symtab on each iteration. If specified, iterate through the provided gdb.Symtabs and extract their full path. As @@ -729,20 +735,12 @@ gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw) /* Make sure there is a definite place to store the value of filename before it is released. */ - symtab_paths.vec.push_back (nullptr); - symtab_paths.vec.back () = filename.release (); + spec.spec.filenames.push_back (nullptr); + spec.spec.filenames.back () = filename.release (); } } - if (symtab_list) - { - const char **files = symtab_paths.vec.data (); - - symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, - symtab_paths.vec.size (), files, false); - } - else - symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, 0, NULL, false); + symbols = search_symbols (spec.spec); /* Count the number of symbols (both symbols and optionally minimal symbols) so we can correctly check the throttle limit. */ diff --git a/gdb/symtab.c b/gdb/symtab.c index 21ac57c39a9..b7b65b98ac8 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -4331,26 +4331,23 @@ info_sources_command (const char *args, int from_tty) printf_filtered ("\n"); } -/* Compare FILE against all the NFILES entries of FILES. If BASENAMES is - non-zero compare only lbasename of FILES. */ +/* Compare FILE against all the entries of FILENAMES. If BASENAMES is + non-zero compare only lbasename of FILENAMES. */ -static int -file_matches (const char *file, const char *files[], int nfiles, int basenames) +static bool +file_matches (const char *file, const std::vector &filenames, + bool basenames) { - int i; + if (filenames.size () == 0) + return 1; - if (file != NULL && nfiles != 0) + for (const char *name : filenames) { - for (i = 0; i < nfiles; i++) - { - if (compare_filenames_for_search (file, (basenames - ? lbasename (files[i]) - : files[i]))) - return 1; - } + name = (basenames ? lbasename (name) : name); + if (compare_filenames_for_search (file, name)) + return 1; } - else if (nfiles == 0) - return 1; + return 0; } @@ -4428,31 +4425,19 @@ sort_search_symbols_remove_dups (std::vector *result) result->end ()); } -/* Search the symbol table for matches to the regular expression REGEXP, - returning the results. - - Only symbols of KIND are searched: - VARIABLES_DOMAIN - search all symbols, excluding functions, type names, - and constants (enums). - if T_REGEXP is not NULL, only returns var that have - a type matching regular expression T_REGEXP. - FUNCTIONS_DOMAIN - search all functions - TYPES_DOMAIN - search all type names - ALL_DOMAIN - an internal error for this function - - Within each file the results are sorted locally; each symtab's global and - static blocks are separately alphabetized. - Duplicate entries are removed. - - When EXCLUDE_MINSYMS is false then matching minsyms are also returned, - otherwise they are excluded. */ +/* See symtab.h. */ std::vector -search_symbols (const char *regexp, enum search_domain kind, - const char *t_regexp, - int nfiles, const char *files[], - bool exclude_minsyms) +search_symbols (const search_symbols_spec &search_spec) { + /* Unpack the search spec. */ + const char *regexp = search_spec.symbol_regexp; + enum search_domain kind = search_spec.kind; + const char *t_regexp = search_spec.type_regexp; + int nfiles = search_spec.filenames.size (); + bool exclude_minsyms = search_spec.exclude_minsyms; + + /* The search. */ const struct blockvector *bv; const struct block *b; int i = 0; @@ -4535,8 +4520,12 @@ search_symbols (const char *regexp, enum search_domain kind, the machinery below. */ expand_symtabs_matching ([&] (const char *filename, bool basenames) { - return file_matches (filename, files, nfiles, - basenames); + /* EXPAND_SYMTABS_MATCHING expects a callback + that returns an integer, not a boolean as + FILE_MATCHES does. */ + return file_matches (filename, + search_spec.filenames, + basenames) ? 1 : 0; }, lookup_name_info::match_any (), [&] (const char *symname) @@ -4620,12 +4609,13 @@ search_symbols (const char *regexp, enum search_domain kind, /* Check first sole REAL_SYMTAB->FILENAME. It does not need to be a substring of symtab_to_fullname as it may contain "./" etc. */ - if ((file_matches (real_symtab->filename, files, nfiles, 0) + if ((file_matches (real_symtab->filename, + search_spec.filenames, false) || ((basenames_may_differ || file_matches (lbasename (real_symtab->filename), - files, nfiles, 1)) + search_spec.filenames, true)) && file_matches (symtab_to_fullname (real_symtab), - files, nfiles, 0))) + search_spec.filenames, false))) && ((!preg.has_value () || preg->exec (SYMBOL_NATURAL_NAME (sym), 0, NULL, 0) == 0) @@ -4836,9 +4826,8 @@ symtab_symbol_info (bool quiet, bool exclude_minsyms, regexp = nullptr; /* Must make sure that if we're interrupted, symbols gets freed. */ - std::vector symbols = search_symbols (regexp, kind, - t_regexp, 0, NULL, - exclude_minsyms); + search_symbols_spec spec (kind, regexp, t_regexp, exclude_minsyms); + std::vector symbols = search_symbols (spec); if (!quiet) { @@ -5077,11 +5066,9 @@ static void rbreak_command (const char *regexp, int from_tty) { std::string string; - const char **files = NULL; - const char *file_name; - int nfiles = 0; + const char *file_name = nullptr; - if (regexp) + if (regexp != nullptr) { const char *colon = strchr (regexp, ':'); @@ -5097,17 +5084,14 @@ rbreak_command (const char *regexp, int from_tty) while (isspace (local_name[colon_index])) local_name[colon_index--] = 0; file_name = local_name; - files = &file_name; - nfiles = 1; regexp = skip_spaces (colon + 1); } } - std::vector symbols = search_symbols (regexp, - FUNCTIONS_DOMAIN, - NULL, - nfiles, files, - false); + search_symbols_spec spec (FUNCTIONS_DOMAIN, regexp); + if (file_name != nullptr) + spec.filenames.push_back (file_name); + std::vector symbols = search_symbols (spec); scoped_rbreak_breakpoints finalize; for (const symbol_search &p : symbols) @@ -6352,17 +6336,14 @@ search_module_symbols (const char *module_regexp, const char *regexp, std::vector results; /* Search for all modules matching MODULE_REGEXP. */ - std::vector modules = search_symbols (module_regexp, - MODULES_DOMAIN, - NULL, 0, NULL, - true); + search_symbols_spec spec1 (MODULES_DOMAIN, module_regexp, nullptr, true); + std::vector modules = search_symbols (spec1); /* Now search for all symbols of the required KIND matching the required regular expressions. We figure out which ones are in which modules below. */ - std::vector symbols = search_symbols (regexp, kind, - type_regexp, 0, - NULL, true); + search_symbols_spec spec2 (kind, regexp, type_regexp, true); + std::vector symbols = search_symbols (spec2); /* Now iterate over all MODULES, checking to see which items from SYMBOLS are in each module. */ diff --git a/gdb/symtab.h b/gdb/symtab.h index 6bd8873042f..f1c7db22505 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -2064,12 +2064,52 @@ private: const symbol_search &sym_b); }; -extern std::vector search_symbols (const char *, - enum search_domain, - const char *, - int, - const char **, - bool); +/* When searching for symbols using the SEARCH_SYMBOLS function, one of + these structures is used as the search specification. */ +struct search_symbols_spec +{ + /* The kind of symbols are we searching for. + VARIABLES_DOMAIN - Search all symbols, excluding functions, type + names, and constants (enums). + FUNCTIONS_DOMAIN - Search all functions.. + TYPES_DOMAIN - Search all type names. + MODULES_DOMAIN - Search all Fortran modules. + ALL_DOMAIN - Not valid for this function. */ + enum search_domain kind; + + /* Regular expression to match against the symbol name. */ + const char *symbol_regexp = nullptr; + + /* Regular expression to match against the type of the symbol. */ + const char *type_regexp = nullptr; + + /* When this flag is false then minsyms that match SYMBOL_REGEXP will be + included in the results, otherwise they are excluded. */ + bool exclude_minsyms = false; + + /* The set of source files to search in for matching symbols. */ + std::vector filenames; + + /* Constructor. */ + search_symbols_spec (enum search_domain kind, + const char *symbol_regexp = nullptr, + const char *type_regexp = nullptr, + bool exclude_minsyms = false) + : kind (kind), + symbol_regexp (symbol_regexp), + type_regexp (type_regexp), + exclude_minsyms (exclude_minsyms) + { /* Nothing. */ } +}; + +/* Search the symbol table for matches as defined by SEARCH_SPEC. + + Within each file the results are sorted locally; each symtab's global + and static blocks are separately alphabetized. Duplicate entries are + removed. */ + +extern std::vector search_symbols + (const struct search_symbols_spec &search_spec); /* When searching for Fortran symbols within modules (functions/variables) we return a vector of this type. The first item in the pair is the