[binutils-gdb] gdb: Support UTF-8 output on MS-Windows terminal
Eli Zaretskii
eliz@sourceware.org
Thu Jan 22 11:06:18 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=43c658ff0cf2bf0b407a563b0de2a36d55e2d5df
commit 43c658ff0cf2bf0b407a563b0de2a36d55e2d5df
Author: Eli Zaretskii <eliz@gnu.org>
Date: Thu Jan 22 13:03:13 2026 +0200
gdb: Support UTF-8 output on MS-Windows terminal
This detects when the Windows Terminal uses codepage 65001
(a.k.a. "UTF-8") for output, and sets the default host
charset to UTF-8 in that case. It also enables Emoji
styling, as the Windows terminal supports it in that case.
* gdb/charset.c (INIT_GDB_FILE) [USE_WIN32API]: If the Windows
console uses codepage 65001, set default host charset to UTF-8, and
switch to the "C" locale, to prevent Windows from interpreting UTF-8
sequences written to the console.
* gdb/mingw-hdep.c (windows_initialize_console): Don't disable Emoji
here...
* gdb/charset.c (INIT_GDB_FILE) [USE_WIN32API]: ...disable them here
instead, and only if the console doesn't use UTF-8.
Diff:
---
gdb/charset.c | 24 +++++++++++++++++++++---
gdb/charset.h | 4 ++++
gdb/mingw-hdep.c | 26 ++++++++++++++++++++++----
3 files changed, 47 insertions(+), 7 deletions(-)
diff --git a/gdb/charset.c b/gdb/charset.c
index 7c6cd938c32..eaddfb57098 100644
--- a/gdb/charset.c
+++ b/gdb/charset.c
@@ -19,6 +19,7 @@
#include "charset.h"
#include "cli/cli-cmds.h"
+#include "cli/cli-style.h"
#include "gdbsupport/gdb_obstack.h"
#include "gdbsupport/gdb_wait.h"
#include "charset-list.h"
@@ -1009,11 +1010,28 @@ INIT_GDB_FILE (charset)
{
/* "CP" + x<=5 digits + paranoia. */
static char w32_host_default_charset[16];
-
- snprintf (w32_host_default_charset, sizeof w32_host_default_charset,
- "CP%d", GetACP());
+ unsigned codepage = mingw_get_codeset ();
+
+ /* The rest of the code expects a literal "UTF-8" and doesn't know
+ anything about codepage 65001. */
+ if (codepage == 65001)
+ {
+ strcpy (w32_host_default_charset, "UTF-8");
+ /* This is needed to force Windows CRT output functions treat
+ output as simple stream of bytes, instead of trying to
+ interpret it as encoded non-ASCII text, which will fail if
+ the system locale's codeset is NOT UTF-8. */
+ setlocale (LC_CTYPE, "C");
+ }
+ else
+ snprintf (w32_host_default_charset, sizeof w32_host_default_charset,
+ "CP%u", codepage);
auto_host_charset_name = w32_host_default_charset;
auto_target_charset_name = auto_host_charset_name;
+
+ /* Windows Terminal supports Emoji when using UTF-8 output. */
+ if (strcmp (w32_host_default_charset, "UTF-8") != 0)
+ no_emojis ();
}
#endif
#endif
diff --git a/gdb/charset.h b/gdb/charset.h
index 6cfab83b896..431590f5000 100644
--- a/gdb/charset.h
+++ b/gdb/charset.h
@@ -165,4 +165,8 @@ char host_letter_to_control_character (char c);
#define HOST_UTF32 "UTF-32LE"
#endif
+#ifdef __MINGW32__
+ unsigned int mingw_get_codeset ();
+#endif
+
#endif /* GDB_CHARSET_H */
diff --git a/gdb/mingw-hdep.c b/gdb/mingw-hdep.c
index 1fad256bc42..efad50c4cbe 100644
--- a/gdb/mingw-hdep.c
+++ b/gdb/mingw-hdep.c
@@ -24,10 +24,10 @@
#include "gdbsupport/event-loop.h"
#include "gdbsupport/gdb_select.h"
#include "inferior.h"
-#include "cli/cli-style.h"
#include "command.h"
#include "cli/cli-cmds.h"
#include "terminal.h"
+#include "charset.h"
#include <windows.h>
#include <signal.h>
@@ -258,9 +258,6 @@ windows_initialize_console ()
}
else if (hstdout != INVALID_HANDLE_VALUE)
mingw_use_console_color_apis = -1; /* valid, but not a console device */
-
- if (mingw_use_console_color_apis > 0)
- no_emojis ();
}
void
@@ -440,6 +437,27 @@ gdb_console_fputs (const char *linebuf, FILE *fstream)
return 1;
}
+unsigned int
+mingw_get_codeset ()
+{
+ unsigned int default_codepage = GetACP ();
+ unsigned int output_codepage = GetConsoleOutputCP ();
+
+ /* Multibyte writes will not work correctly if written one byte at a
+ time, which is what gdb_console_fputs above does. So if they set
+ the console's output to use UTF-8, only use that if we have
+ successfully set up the terminal for Virtual Terminal Sequences,
+ and are using 'fputs' directly. */
+ if (output_codepage == 0 /* GetConsoleOutputCP failed */
+ || (output_codepage == 65001
+ && output_codepage != default_codepage
+ && !(mingw_use_console_color_apis < 0
+ && hstdout != INVALID_HANDLE_VALUE
+ && orig_console_mode != 0)))
+ return default_codepage;
+ return output_codepage;
+}
+
/* See inferior.h. */
tribool
More information about the Gdb-cvs
mailing list