Remove target: prefix from gdb_sysroot in find_separate_debug_file
authorTom Tromey <tromey@adacore.com>
Wed, 21 Dec 2022 20:57:45 +0000 (13:57 -0700)
committerTom Tromey <tromey@adacore.com>
Mon, 2 Jan 2023 13:48:31 +0000 (06:48 -0700)
I noticed that, when using gdbserver, gdb might print:

Reading /usr/lib/debug/lib64//libcap.so.2.48-2.48-4.fc36.x86_64.debug from remote target...
Reading target:/usr/lib/debug/lib64//libcap.so.2.48-2.48-4.fc36.x86_64.debug from remote target...

The second line has the "target:" prefix, but from the code it's clear
that this string is being passed verbatim to gdbserver -- which seems
wrong.

I filed PR remote/29929 for this.

The problem here is that find_separate_debug_file uses gdb_sysroot
without checking to see if it starts with the "target:" prefix.  This
patch changes this code to be a little more careful.

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

gdb/symfile.c

index 7f9cada695b611e3221a24f39e7c3c749cfec54f..e0942dfb22d69f982a5a1e9d8a5b943a04b30065 100644 (file)
@@ -1470,19 +1470,32 @@ find_separate_debug_file (const char *dir,
            return debugfile;
 
          /* If the file is in the sysroot, try using its base path in
-            the sysroot's global debugfile directory.  */
-         debugfile = target_prefix ? "target:" : "";
-         debugfile += gdb_sysroot;
-         debugfile += debugdir;
-         debugfile += "/";
-         debugfile += base_path;
-         debugfile += "/";
-         debugfile += debuglink;
-
-         if (separate_debug_file_exists (debugfile, crc32, objfile))
-           return debugfile;
+            the sysroot's global debugfile directory.  GDB_SYSROOT
+            might refer to a target: path; we strip the "target:"
+            prefix -- but if that would yield the empty string, we
+            don't bother at all, because that would just give the
+            same result as above.  */
+         if (gdb_sysroot != "target:")
+           {
+             debugfile = target_prefix ? "target:" : "";
+             if (startswith (gdb_sysroot, "target:"))
+               {
+                 std::string root = gdb_sysroot.substr (strlen ("target:"));
+                 gdb_assert (!root.empty ());
+                 debugfile += root;
+               }
+             else
+               debugfile += gdb_sysroot;
+             debugfile += debugdir;
+             debugfile += "/";
+             debugfile += base_path;
+             debugfile += "/";
+             debugfile += debuglink;
+
+             if (separate_debug_file_exists (debugfile, crc32, objfile))
+               return debugfile;
+           }
        }
-
     }
 
   return std::string ();