Handle encoding failures in Windows thread names
authorTom Tromey <tromey@adacore.com>
Tue, 19 Apr 2022 17:21:35 +0000 (11:21 -0600)
committerTom Tromey <tromey@adacore.com>
Tue, 26 Apr 2022 18:54:05 +0000 (12:54 -0600)
Internally at AdaCore, we noticed that the new Windows thread name
code could fail.  First, it might return a zero-length string, but in
gdb conventions it should return nullptr instead.  Second, an encoding
failure could wind up showing replacement characters to the user; this
is confusing and not useful; it's better to recognize such errors and
simply discard the name.  This patch makes both of these changes.

gdb/nat/windows-nat.c

index bd1b94591456884476cb382236eb7617c13221f4..c8db19439f3dbae4dec9da5f0d20ba661a48fa9c 100644 (file)
@@ -119,12 +119,23 @@ windows_thread_info::thread_name ()
       HRESULT result = GetThreadDescription (h, &value);
       if (SUCCEEDED (result))
        {
-         size_t needed = wcstombs (nullptr, value, 0);
-         if (needed != (size_t) -1)
+         int needed = WideCharToMultiByte (CP_ACP, 0, value, -1, nullptr, 0,
+                                           nullptr, nullptr);
+         if (needed != 0)
            {
-             name.reset ((char *) xmalloc (needed));
-             if (wcstombs (name.get (), value, needed) == (size_t) -1)
-               name.reset ();
+             /* USED_DEFAULT is how we detect that the encoding
+                conversion had to fall back to the substitution
+                character.  It seems better to just reject bad
+                conversions here.  */
+             BOOL used_default = FALSE;
+             gdb::unique_xmalloc_ptr<char> new_name
+               ((char *) xmalloc (needed));
+             if (WideCharToMultiByte (CP_ACP, 0, value, -1,
+                                      new_name.get (), needed,
+                                      nullptr, &used_default) == needed
+                 && !used_default
+                 && strlen (new_name.get ()) > 0)
+               name = std::move (new_name);
            }
          LocalFree (value);
        }