From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id WtbyCt9dxWrgUwcAWB0awg (envelope-from ) for ; Tue, 06 Oct 2026 16:45:19 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=b3vbb3CA; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id DF3E11E051; Tue, 06 Oct 2026 16:45:18 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 253D71E047 for ; Tue, 06 Oct 2026 16:45:16 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 87D0B48FDEC3 for ; Tue, 6 Oct 2026 20:45:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 87D0B48FDEC3 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=b3vbb3CA Received: from mail-dy1-x1330.google.com (mail-dy1-x1330.google.com [IPv6:2607:f8b0:4864:20::1330]) by sourceware.org (Postfix) with ESMTPS id 3176048FDEC3 for ; Tue, 6 Oct 2026 20:44:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3176048FDEC3 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3176048FDEC3 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1330 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1791319490; cv=none; b=QJNA9sTsZy6jqsODglfuuHQiCly5NKr0Ufxo/2WrufO2RmufqZRncCDZa9Rexd303lVg+g/NDq3dnT6ATI5dmGR5t9oQh020xa1dXrxPQ2kG/K7wQLlQe8ImhPBw8pVmvM1kqayifg7hFV8djSxC32cvAFNLURJHcRzdeZtOaZM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1791319490; c=relaxed/simple; bh=MkZECqrWvK2zM28qmVHB8LKbScLNz2dueoXkix0pex4=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=SBHOywuPX/J2aD+1tYqRNvllPTJOXnQBQG8SV4U2wp8GZXZGhKVAMQz+xIVSioJG9cWdoE50UMuXUBEVfqzpEejDR2XLDV1A+u03F26wHER308NV47K9gC3llEYdt8hAoGNSV2kpdLATu/vKfqP1bdbekQ22w4ISG2xOfy3yt5Q= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=b3vbb3CA DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3176048FDEC3 Received: by mail-dy1-x1330.google.com with SMTP id 5a478bee46e88-34c89609923so3100566eec.1 for ; Tue, 06 Oct 2026 13:44:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1791319489; x=1791924289; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=FbQPYeq6z1ZLZlSTPsVlJSwzcTkII7Ur/pZVC9jXw9s=; b=b3vbb3CAAyEO8P1axAloNJESOwMIA3t9YLg9FCJj/X2nHKu0q2lWY7XbV1fOyRvqSL YNb5XE0fJAMGgNgjwzBFAbN2u5IvKBt6HkqWqVTHddlCs6k+SOfX2/KiTygTjREY6jjF LSb/aYfLmkd6/F3WVv3VetNQbs7b2T82wJ7nif0YfAns40C1C7+EVgQNcV8HEc1rzbHL DnCtdvFpnldcngJh3b3yHVkyFe7ysReXcUs+k57U62VBc5fGq8HmMMRSCiD8fd+i0FBK TdXXBeOO6fD1DQTEcXOuOtcp99yIcgw1jRP72Cb9u5gvWR1etnUYN/MkUjAr8Vn/0pKs WDOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791319489; x=1791924289; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=FbQPYeq6z1ZLZlSTPsVlJSwzcTkII7Ur/pZVC9jXw9s=; b=T4cuWZl4gO63D7DjEDfjqywDh/53s+XPiqp24WiVLPaxhDr1zRjC3XbuaEGmFfzSYa 6vCgb3ohjc2WU1dqRmas3A2mwH9OeCu3eGPzpZsOdLCg2QIxqGqdTimQK7SYHfquFcN3 vVI1MSevu4A3CX8jISHcYg1E3UWuiCCbY7aYgxnRGJz3ch9KXD/Du1lyO19JU3QIxn7C L90b45SOqihObZ1qCu4U70pZADrq07054ectrjB1Um2AJoOaqqp+/h443kzq6kUTjKV1 HPCpmsdNuLp2y0M6DPfQdkY3/os4IMDR4RLWlAr0+rmyZzUqstBUWvN1MsxvlodPQsa2 bO0w== X-Gm-Message-State: AFuF++knekf/lGynTieAzBLZqxZr2NE3zKUI9vVbzciIoHVx1kA3mdfy BejxRRbC6Qdcpiep0toU0LCGP5O1vuMPNV8cEbGJaC2OdP6QoLiErH5DIv+f/872EBvLB3sjpbO CC7RX X-Gm-Gg: AYBFou2tgNAgPYQnB74klogQZVOx54QPl2dKLpXkyBk61JfXnITma/iQZTfX+dWIi6J qgAHO9LRrNMUgKZAOZNAGpFdz6eHUqZib6Fgnb5SMZBRfIeIlSAsthiyNqO7plrOnqt7182mGsg ROcNb8mL0KlIukcqseIfxvTHtSw1STU25nMb9XyXAYWJrIKEnEMp0nQqYRYkBO3vqviV5Z3Y9Nn rS8WqL5DUxkJCm0GssMuDr99PGbDQAXWc6In2bBHceEk4rjfvIcs8dhHHr8z7t8xRqNP3F73lHp lJqYO13RnVZA6LkMavbU5oyHa8HQ3D0M9PD6mcFXrGO2OqdsfYaqjsI7roECWnb+xVVNA6cfF2R 4qO/vB1xuRXxoNHfLviQ/MygVA0cr+axtu4Vwr5a78XKzvSqCW0PPrvFEBUOBHDAYGM/tkkvd5B U2Ll4gbJMEY5DSsS+IOzS6hHVAyCWgiirby2ldw7EYbOKyvsGo24j33fdxgFS2EAt32Q5T/ZI3e oRwYNe9xP8PscFnv+T7GNOXwtFJ4Q3zRX0/m6i1 X-Received: by 2002:a05:7300:fb10:b0:33e:3f5b:3ffa with SMTP id 5a478bee46e88-3515dd82050mr459eec.10.1791319488292; Tue, 06 Oct 2026 13:44:48 -0700 (PDT) Received: from mandiga ([2804:1b3:a7c1:f532:9440:6cbd:710d:3568]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-3515af90521sm1887428eec.19.2026.10.06.13.44.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2026 13:44:47 -0700 (PDT) From: Adhemerval Zanella To: gdb-patches@sourceware.org Cc: Thiago Jung Bauermann Subject: [PATCH] gdb: Restrict module drill-down searches to matched modules Date: Tue, 6 Oct 2026 17:43:35 -0300 Message-ID: <20261006204442.2251718-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.53.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org search_module_symbols (used by -symbol-info-module-{functions,variables} and the 'info module' subcommands) performs a second global_symbol_searcher search for *all* functions or variables in the program with no module filter. This expands every compunit, and only afterwards keeps the symbols whose qualified name starts with a matched module prefix. The modules are already known from the first search, so restrict the second one to the symbols qualified by one of them. Their names are collected in a set, and the new global_symbol_searcher::set_scope_filter makes the search skip every name that is not prefixed by one of them. It is checked while expanding symtabs, so that the compunits of the other modules are not expanded at all, and while collecting symbols and minimal symbols. Handing the searcher a '^\(mod1\|mod2\|...\)::' regexp instead would restrict the search in the same way, but gdb matches regexps with libiberty's backtracking matcher, which tries every alternative for each name; with a few thousand modules that costs more than the compunit expansion it avoids. Also return early when no module matched, skipping the second search entirely. On a 2000-module synthetic Fortran benchmark, cold medians: -symbol-info-module-functions --module : 0.97 s -> 0.05 s -symbol-info-module-variables --module : 0.34 s -> 0.06 s with a regexp matching 100 of the modules: -symbol-info-module-variables --module : 0.38 s -> 0.08 s and the searches that match every module are not penalised: -symbol-info-module-variables: 1.36 s -> 1.28 s -symbol-info-module-functions: 1.86 s -> 1.16 s -symbol-info-module-variables --name grid_: 0.39 s -> 0.39 s Change-Id: I9d1554fce539f89b6d1f09802b6d24469bec49cf --- gdb/symtab.c | 40 +++++++++++++++++++-- gdb/symtab.h | 22 ++++++++++-- gdb/testsuite/gdb.fortran/info-modules.exp | 13 +++++++ gdb/testsuite/gdb.mi/mi-fortran-modules.exp | 13 +++++++ 4 files changed, 83 insertions(+), 5 deletions(-) diff --git a/gdb/symtab.c b/gdb/symtab.c index b082a488b88..9551f3cdc74 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -4783,6 +4783,9 @@ global_symbol_searcher::symbol_matches if (!name_matches (name_regex, sym->natural_name ())) return false; + if (!scope_filter_matches (sym->natural_name ())) + return false; + switch (m_kind) { case symbol_search_kind::VARIABLE: @@ -4826,7 +4829,25 @@ global_symbol_searcher::msymbol_matches if (!is_suitable_msymbol (msymbol)) return false; - return name_matches (name_regex, msymbol->natural_name ()); + if (!name_matches (name_regex, msymbol->natural_name ())) + return false; + + return scope_filter_matches (msymbol->natural_name ()); +} + +/* See symtab.h. */ + +bool +global_symbol_searcher::scope_filter_matches (const char *name) const +{ + if (m_scope_filter == nullptr) + return true; + + const std::string_view full_name (name); + const size_t sep = full_name.find ("::"); + + return (sep != std::string_view::npos + && m_scope_filter->contains (full_name.substr (0, sep))); } /* See symtab.h. */ @@ -4851,7 +4872,8 @@ global_symbol_searcher::expand_symtabs &lookup_name_info::match_any (), [&] (const char *symname) { - return name_matches (name_regex, symname); + return (name_matches (name_regex, symname) + && scope_filter_matches (symname)); }, NULL, SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK, @@ -6723,12 +6745,24 @@ search_module_symbols (const char *module_regexp, const char *regexp, spec1.set_exclude_minsyms (true); std::vector modules = spec1.search (); + if (modules.empty ()) + return results; + /* Now search for all symbols of the required KIND matching the required regular expressions. We figure out which ones are in which modules - below. */ + below. + + Only symbols of the modules found above can be part of the result, + so restrict the search to them. This avoids expanding the symtabs of + every other module. */ + gdb::unordered_set module_names; + for (const symbol_search &p : modules) + module_names.insert (p.symbol->print_name ()); + global_symbol_searcher spec2 (kind, regexp); spec2.set_symbol_type_regexp (type_regexp); spec2.set_exclude_minsyms (true); + spec2.set_scope_filter (&module_names); std::vector symbols = spec2.search (); /* Now iterate over all MODULES, checking to see which items from diff --git a/gdb/symtab.h b/gdb/symtab.h index bd719af6669..0bce7c6a3a2 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -30,6 +30,7 @@ #include "gdbsupport/gdb_regex.h" #include "gdbsupport/enum-flags.h" #include "gdbsupport/function-view.h" +#include "gdbsupport/unordered_set.h" #include "gdbsupport/iteration-status.h" #include #include @@ -2645,6 +2646,14 @@ class global_symbol_searcher m_max_search_results = max_search_results; } + /* Only consider symbols whose name is qualified by one of SCOPES, that + is, starts with one of them followed by "::". SCOPES must outlive + the search. */ + void set_scope_filter (const gdb::unordered_set *scopes) + { + m_scope_filter = scopes; + } + /* Search the symbols from all objfiles in the current program space looking for matches as defined by the current state of this object. @@ -2678,6 +2687,13 @@ class global_symbol_searcher of SIZE_MAX, there is no "unlimited". */ size_t m_max_search_results = SIZE_MAX; + /* If not nullptr, the scopes symbol names must be qualified by, see + set_scope_filter. */ + const gdb::unordered_set *m_scope_filter = nullptr; + + /* Return true if NAME passes M_SCOPE_FILTER. */ + bool scope_filter_matches (const char *name) const; + /* Compile M_SYMBOL_NAME_REGEXP, if set. This function normalizes the spacing when it detects a C++ operator in the @@ -2691,12 +2707,14 @@ class global_symbol_searcher bool symtab_matches_filenames (symtab *symtab) const; /* Return true if SYM is of kind M_KIND, is in a file matching - M_FILENAMES, and matches NAME_REGEX and TYPE_REGEX. */ + M_FILENAMES, passes M_SCOPE_FILTER, and matches NAME_REGEX and + TYPE_REGEX. */ bool symbol_matches (const symbol *sym, const std::optional &name_regex, const std::optional &type_regex) const; - /* Return true if MSYMBOL is of kind M_KIND and matches NAME_REGEX. + /* Return true if MSYMBOL is of kind M_KIND, passes M_SCOPE_FILTER, and + matches NAME_REGEX. This function also filters out the minimal symbols artificially created by GDB. */ diff --git a/gdb/testsuite/gdb.fortran/info-modules.exp b/gdb/testsuite/gdb.fortran/info-modules.exp index f94df7f1655..af31cf7c799 100644 --- a/gdb/testsuite/gdb.fortran/info-modules.exp +++ b/gdb/testsuite/gdb.fortran/info-modules.exp @@ -160,3 +160,16 @@ GDBInfoModuleSymbols::check_entry "${srcfile}" "mod1" "21" \ "${real4} mod1::mod1_var_1;" GDBInfoModuleSymbols::check_no_entry "${srcfile}" ".*" GDBInfoModuleSymbols::check_no_entry "${srcfile2}" ".*" + +GDBInfoModuleSymbols::run_command "info module functions -m mod1 SUB_M1_A" +GDBInfoModuleSymbols::check_header \ + "All functions matching regular expression \"SUB_M1_A\", in all modules matching regular expression \"mod1\":" +GDBInfoModuleSymbols::check_entry "${srcfile}" "mod1" "25" \ + "void mod1::sub_m1_a\\(${integer4}\\);" +GDBInfoModuleSymbols::check_no_entry "${srcfile}" ".*" +GDBInfoModuleSymbols::check_no_entry "${srcfile2}" ".*" + +gdb_test "info module functions -m nomatch" \ + "^All functions in all modules matching regular expression \"nomatch\":" +gdb_test "info module variables -m nomatch" \ + "^All variables in all modules matching regular expression \"nomatch\":" diff --git a/gdb/testsuite/gdb.mi/mi-fortran-modules.exp b/gdb/testsuite/gdb.mi/mi-fortran-modules.exp index 51e810c9271..69f9124a61f 100644 --- a/gdb/testsuite/gdb.mi/mi-fortran-modules.exp +++ b/gdb/testsuite/gdb.mi/mi-fortran-modules.exp @@ -158,3 +158,16 @@ gdb_test_multiple $cmd $test -prompt $mi_gdb_prompt$ { } } } + +# Check that a --module regexp matching no modules gives an empty +# result, and no error. +mi_gdb_test "108-symbol-info-module-functions --module nomatch" \ + "108\\^done,symbols=\\\[\\\]" \ + "-symbol-info-module-functions --module nomatch" + +# Check that it still honours Fortran's case insensitivity. +set mod1_check_all_re \ + "\{module=\"mod1\",files=\\\[\{filename=\"\[^\"\]+$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"21\",name=\"mod1::check_all\",type=\"void \\(void\\)\",description=\"void mod1::check_all\\(void\\);\"\}\\\]\}\\\]\}" +mi_gdb_test "109-symbol-info-module-functions --module mod1 --name CHECK_ALL" \ + "109\\^done,symbols=\\\[${mod1_check_all_re}(,${mod1_check_all_re})*\\\]" \ + "-symbol-info-module-functions --module mod1 --name CHECK_ALL" -- 2.53.0