From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Guinevere Larsen <guinevere@redhat.com>,
Fangrui Song <maskray@sourceware.org>
Subject: Re: [PATCH v2] gdb: fix filename matching in skiplist_entry::do_skip_gfile_p
Date: Mon, 09 Feb 2026 15:15:03 +0000 [thread overview]
Message-ID: <871piuc5jc.fsf@redhat.com> (raw)
In-Reply-To: <87ldh8dvvs.fsf@redhat.com>
Andrew Burgess <aburgess@redhat.com> writes:
> Guinevere Larsen <guinevere@redhat.com> writes:
>
>> GDB is incorrectly matching -gfile skip entries. This is a regression
>> introduced by the following commit:
>>
>> commit 02646a4c561ec88491114b87950cbb827c7d614c
>> Author: Fangrui Song <maskray@sourceware.org>
>> Date: Sun Dec 29 14:57:44 2024 -0800
>>
>> skip -gfile: call fnmatch without FNM_FILE_NAME
>>
>> The author made the reasonable, but unfortunately incorrect, assumption
>> that glibc's fnmatch, and consequently gdb_filename_fnmatch, will return
>> the integer equivalent of a boolean (that is, 0 if the filenames do *not*
>> match, non-zero if they match), but that is incorrect. This made it so
>> using `skip -gfile` would skip all functions except the ones that are
>> meant to be skipped. This commit fixes that inverted logic.
>>
>> This incorrect matching masked a different bug, that we were treating
>> all user-provided gfiles as absolute paths, and the gdb.base/skip.exp
>> test happened to not catch it because the "skip.c" file is different
>> enough to exit earlier in the comparisons. This was solved by making it
>> so if the gfile is not absolute, the regex "*/" is prepended, allowing
>> for any number of directories before the first user-provided one, but
>> ensuring that the beginning of the directory must match what the user
>> provided.
>>
>> The limitation of this approach is that, if a user has given the regex
>> "a/c*.c", and the inferior contains both "/b/a/code.c" and
>> "/c/a/code.c" and is running on the folder /b, functions from both may
>> be skipped when it would be reasonable for the user to expect only
>> /b/a/code.c to be skipped. This is done anyway because I believe the
>> likelihood of something like this actually happening is incredibly low,
>> and it was the behavior of GDB before the aforementioned commit so we'll
>> just be returning to previous behavior.
>
> For what it's worth, I'm not convinced by the original patch. Sadly
> there are no tests with the original patch, but based on the commit
> message I think what they original wanted was, given a directory tree
> like:
>
> /usr/include/first_header.h
> /usr/include/dir1/some_header.h
> /usr/include/dir2/other_header.h
>
> They can just:
>
> (gdb) skip -gfile /usr/include/*.h
>
> And skip all three headers.
>
> The problem I have with this is that I can no longer skip just the files
> in one directory, so given:
>
> /foo/file_a.c
> /foo/bar/file_b.c
>
> I can no longer do:
>
> (gdb) skip -gfile /foo/*.c
>
> And only skip 'file_a.c', the '*' here will always match both 'file_a.c'
> and 'bar/file_b.c', which I think is unfortunate.
>
> I wonder if a better approach would be to add something like bash's '**'
> globstar feature, which matches 0 or more sub-directories. In the
> original case the user could then:
>
> (gdb) skip -gfile /usr/include/**/*.h
>
> This would match all three headers from the original example. And in
> the second example:
>
> (gdb) skip -gfile /foo/*.c
>
> Would still only match 'file_a.c' as it currently does. If we wanted to
> match both, then:
>
> (gdb) skip -gfile /foo/**/*.c
>
> Would do the trick.
>
> Unfortunately, fnmatch doesn't support '**' matching, so we'd have to
> roll our own, but I think it would be worth it.
>
> Given the above, my vote would be to not merge this fix, but instead
> revert commit 02646a4c561ec8849111, then we could make an attempt at
> adding a '**' feature.
>
> We could merge this fix, but doing that would make the changed behaviour
> that commit 02646a4c561ec8849111 tried to introduced actually work, at
> which point people might start depending on it. Right now
> 02646a4c561ec8849111 is broken, so revering it, even though it made it
> into GDB 17, should be OK I think.
>
> Anyway, that's just my thoughts, not sure how others will feel.
CC-ing Fangrui Song (original patch author).
I'm planning to revert commit:
commit 02646a4c561ec88491114b87950cbb827c7d614c
Date: Sun Dec 29 14:57:44 2024 -0800
skip -gfile: call fnmatch without FNM_FILE_NAME
In the gdb-17-branch and master branch on Wednesday. As the bug the
Guinevere mentions, this patch has introduced a regression, and as I
believe I have shown, this patch has changed GDB behaviour in a
non-backward compatible way.
I'll then take a look at implementing support for '**' as mentioned
above as I believe this will solve the original issue in a backward
compatible way.
If any other global maintainer disagrees with this plan, speak out and
I'll not go ahead with this.
Thanks,
Andrew
>
> Thanks,
> Andrew
>
>
>
>>
>> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33872
>> ---
>> gdb/skip.c | 15 ++++++++++++++-
>> gdb/testsuite/gdb.base/skip.exp | 15 +++++++++++++++
>> 2 files changed, 29 insertions(+), 1 deletion(-)
>>
>> diff --git a/gdb/skip.c b/gdb/skip.c
>> index 1255c7d2152..5770d6251a8 100644
>> --- a/gdb/skip.c
>> +++ b/gdb/skip.c
>> @@ -548,7 +548,20 @@ skiplist_entry::do_skip_gfile_p (const symtab_and_line &function_sal) const
>> /* Note: symtab_to_fullname caches its result, thus we don't have to. */
>> const char *fullname = symtab_to_fullname (function_sal.symtab);
>>
>> - result = gdb_filename_fnmatch (m_file.c_str (), fullname, FNM_NOESCAPE);
>> + /* If the pattern does not correspond to an absolute path, add a glob
>> + that accepts any leading path. While this is not technically
>> + correct, it is very likely that a user wished to skip /a/b/code.c and
>> + not skip /c/b/code.c, and both files are relevant to the project.
>> + Plus, this is how GDB has always worked, so users are likely expecting
>> + that behavior. */
>> + std::string glob = "*/";
>> + if (IS_ABSOLUTE_PATH (m_file.c_str ()))
>> + glob = m_file;
>> + else
>> + glob += m_file;
>> +
>> + result = gdb_filename_fnmatch
>> + (glob.c_str (), fullname, FNM_NOESCAPE) == 0;
>> }
>>
>> if (debug_skip)
>> diff --git a/gdb/testsuite/gdb.base/skip.exp b/gdb/testsuite/gdb.base/skip.exp
>> index 4541e61ec00..7cec1fc7021 100644
>> --- a/gdb/testsuite/gdb.base/skip.exp
>> +++ b/gdb/testsuite/gdb.base/skip.exp
>> @@ -336,3 +336,18 @@ with_test_prefix "skip delete completion" {
>> test_gdb_complete_none "skip delete a1"
>> test_gdb_complete_none "skip delete 2-33"
>> }
>> +
>> +# PR gdb/33872 was a regression that would happen when using
>> +# skip -gfile and a full path had to be matched. The logic had
>> +# been inverted and it wold skip all files but the one with the
>> +# one we wanted to skip
>> +with_test_prefix "PR gdb/33872" {
>> + gdb_test "skip -gfi /unused/path/*" \
>> + "File\\(s\\) /unused/path/\\* will be skipped when stepping\."
>> +
>> + if {![runto_main]} {
>> + return
>> + }
>> +
>> + gdb_test "step" "bar \\\(\\\) at .*"
>> +}
>>
>> base-commit: a6d46a04ea3e165c0ce2f11cd9d68bdcb81f4e4e
>> --
>> 2.52.0
next prev parent reply other threads:[~2026-02-09 15:15 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-03 18:55 Guinevere Larsen
2026-02-04 21:47 ` Andrew Burgess
2026-02-05 12:43 ` Guinevere Larsen
2026-02-09 15:15 ` Andrew Burgess [this message]
2026-02-11 14:33 ` Andrew Burgess
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=871piuc5jc.fsf@redhat.com \
--to=aburgess@redhat.com \
--cc=gdb-patches@sourceware.org \
--cc=guinevere@redhat.com \
--cc=maskray@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox