]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Revert "skip -gfile: call fnmatch without FNM_FILE_NAME"
authorAndrew Burgess <aburgess@redhat.com>
Mon, 9 Feb 2026 16:31:23 +0000 (16:31 +0000)
committerAndrew Burgess <aburgess@redhat.com>
Wed, 11 Feb 2026 12:54:13 +0000 (12:54 +0000)
This reverts commit 02646a4c561ec88491114b87950cbb827c7d614c.  See:

  https://inbox.sourceware.org/gdb-patches/20260203185528.946918-1-guinevere@redhat.com

This commit introduced a non backward compatible change to how GDB
handled skip files.  Something like:

  skip -gfile dir/*.c

no longer matches every file within 'dir/', but now matches every file
in 'dir/' and within every sub-directory of 'dir/', which might not be
what the user wanted.

The original intention behind the commit is solid, we just need to
find a better implementation.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33872

gdb/doc/gdb.texinfo
gdb/skip.c
gdb/symtab.c
gdb/utils.c

index c6a805b3ea0e9a678c6d3a574147f5f30ba92b71..5169be1965c5fd92c85fdc269c05260a386f68e7 100644 (file)
@@ -6960,9 +6960,7 @@ Functions in @var{file} will be skipped over when stepping.
 @itemx -gfi @var{file-glob-pattern}
 @cindex skipping over files via glob-style patterns
 Functions in files matching @var{file-glob-pattern} will be skipped
-over when stepping.  The directory separator character @file{/} is treated as a
-regular character, so it can be matched by wildcard characters @file{*} and
-@file{?}.
+over when stepping.
 
 @smallexample
 (@value{GDBP}) skip -gfi utils/*.c
index 1255c7d2152b8b7706d79f6af1a210511905e14d..f4156d93d4071cde9c56dea27c7ae6d09e2824f1 100644 (file)
@@ -530,7 +530,7 @@ skiplist_entry::do_skip_gfile_p (const symtab_and_line &function_sal) const
   /* Check first sole SYMTAB->FILENAME.  It may not be a substring of
      symtab_to_fullname as it may contain "./" etc.  */
   if (gdb_filename_fnmatch (m_file.c_str (), function_sal.symtab->filename (),
-                           FNM_NOESCAPE) == 0)
+                           FNM_FILE_NAME | FNM_NOESCAPE) == 0)
     result = true;
 
   /* Before we invoke symtab_to_fullname, which is expensive, do a quick
@@ -541,14 +541,14 @@ skiplist_entry::do_skip_gfile_p (const symtab_and_line &function_sal) const
   else if (!basenames_may_differ
       && gdb_filename_fnmatch (lbasename (m_file.c_str ()),
                               lbasename (function_sal.symtab->filename ()),
-                              FNM_NOESCAPE) != 0)
+                              FNM_FILE_NAME | FNM_NOESCAPE) != 0)
     result = false;
   else
     {
       /* 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);
+      result = compare_glob_filenames_for_search (fullname, m_file.c_str ());
     }
 
   if (debug_skip)
index 5d02d328694b464ce1adbfbc2ca1294c59c542c5..07436104ce7fad2f361427caddee3c3b3d9af508 100644 (file)
@@ -629,6 +629,40 @@ compare_filenames_for_search (const char *filename, const char *search_name)
              && STRIP_DRIVE_SPEC (filename) == &filename[len - search_len]));
 }
 
+/* Same as compare_filenames_for_search, but for glob-style patterns.
+   Heads up on the order of the arguments.  They match the order of
+   compare_filenames_for_search, but it's the opposite of the order of
+   arguments to gdb_filename_fnmatch.  */
+
+bool
+compare_glob_filenames_for_search (const char *filename,
+                                  const char *search_name)
+{
+  /* We rely on the property of glob-style patterns with FNM_FILE_NAME that
+     all /s have to be explicitly specified.  */
+  int file_path_elements = count_path_elements (filename);
+  int search_path_elements = count_path_elements (search_name);
+
+  if (search_path_elements > file_path_elements)
+    return false;
+
+  if (IS_ABSOLUTE_PATH (search_name))
+    {
+      return (search_path_elements == file_path_elements
+             && gdb_filename_fnmatch (search_name, filename,
+                                      FNM_FILE_NAME | FNM_NOESCAPE) == 0);
+    }
+
+  {
+    const char *file_to_compare
+      = strip_leading_path_elements (filename,
+                                    file_path_elements - search_path_elements);
+
+    return gdb_filename_fnmatch (search_name, file_to_compare,
+                                FNM_FILE_NAME | FNM_NOESCAPE) == 0;
+  }
+}
+
 /* See symtab.h.  */
 
 void
index 061161b1f3a35e56da311c1bfabc3e25a87602c2..ef8ef87bc5b8394938b8dda6750c693fa0a4a068 100644 (file)
@@ -3493,8 +3493,8 @@ wait_to_die_with_timeout (pid_t pid, int *status, int timeout)
 
 #endif /* HAVE_WAITPID */
 
-/* Provide fnmatch compatible function for matching of host files.
-   FNM_NOESCAPE must be set in FLAGS.
+/* Provide fnmatch compatible function for FNM_FILE_NAME matching of host files.
+   Both FNM_FILE_NAME and FNM_NOESCAPE must be set in FLAGS.
 
    It handles correctly HAVE_DOS_BASED_FILE_SYSTEM and
    HAVE_CASE_INSENSITIVE_FILE_SYSTEM.  */
@@ -3502,6 +3502,8 @@ wait_to_die_with_timeout (pid_t pid, int *status, int timeout)
 int
 gdb_filename_fnmatch (const char *pattern, const char *string, int flags)
 {
+  gdb_assert ((flags & FNM_FILE_NAME) != 0);
+
   /* It is unclear how '\' escaping vs. directory separator should coexist.  */
   gdb_assert ((flags & FNM_NOESCAPE) != 0);