https://github.com/charles-zablit created 
https://github.com/llvm/llvm-project/pull/149493

This patch sets the codepage of the parent Windows console to `utf-8` and 
resets it back to the original codepage once `lldb` exits.

This fixes a rendering issue where the characters defined in 
`DiagnosticsRendering.cpp` (`"╰"` for instance) are not rendered properly on 
Windows out of the box, because the default codepage is not `utf-8`.

This solution is based on this [SO 
thread](https://stackoverflow.com/questions/10882277/properly-print-utf8-characters-in-windows-console)
 and [this patch 
downstream](https://github.com/swiftlang/swift/pull/40632/files#diff-e948e4bd7a601e3ca82d596058ccb39326459a4751470eec4d393adeaf516977R37-R38).

rdar://156064500

>From 77bf2b7acb82ea930702c8b0587c019fd48dc0f2 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zab...@apple.com>
Date: Fri, 18 Jul 2025 12:29:31 +0200
Subject: [PATCH] [windows][lldb] force the console to use a UTF-8 codepage

---
 .../Platform/Windows/PlatformWindows.cpp      | 20 +++++++++++++++++++
 .../Platform/Windows/PlatformWindows.h        |  8 ++++++++
 2 files changed, 28 insertions(+)

diff --git a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp 
b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
index c0c26cc5f1954..d3e981de81313 100644
--- a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -41,6 +41,10 @@ LLDB_PLUGIN_DEFINE(PlatformWindows)
 
 static uint32_t g_initialize_count = 0;
 
+#if defined(_WIN32)
+std::optional<UINT> g_prev_console_cp = std::nullopt;
+#endif
+
 PlatformSP PlatformWindows::CreateInstance(bool force,
                                            const lldb_private::ArchSpec *arch) 
{
   // The only time we create an instance is when we are creating a remote
@@ -98,6 +102,7 @@ void PlatformWindows::Initialize() {
     default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
     Platform::SetHostPlatform(default_platform_sp);
 #endif
+    SetConsoleCodePage();
     PluginManager::RegisterPlugin(
         PlatformWindows::GetPluginNameStatic(false),
         PlatformWindows::GetPluginDescriptionStatic(false),
@@ -108,6 +113,7 @@ void PlatformWindows::Initialize() {
 void PlatformWindows::Terminate() {
   if (g_initialize_count > 0) {
     if (--g_initialize_count == 0) {
+      ResetConsoleCodePage();
       PluginManager::UnregisterPlugin(PlatformWindows::CreateInstance);
     }
   }
@@ -808,3 +814,17 @@ extern "C" {
 
   return Status();
 }
+
+void PlatformWindows::SetConsoleCodePage() {
+  #if defined(_WIN32)
+    g_prev_console_cp = GetConsoleOutputCP();
+    SetConsoleOutputCP(CP_UTF8);
+  #endif
+}
+
+void PlatformWindows::ResetConsoleCodePage() {
+  #if defined(_WIN32)
+  if (g_prev_console_cp)
+    SetConsoleOutputCP(*g_prev_console_cp);
+  #endif
+}
diff --git a/lldb/source/Plugins/Platform/Windows/PlatformWindows.h 
b/lldb/source/Plugins/Platform/Windows/PlatformWindows.h
index 771133f341e90..d14aa52e5e1c8 100644
--- a/lldb/source/Plugins/Platform/Windows/PlatformWindows.h
+++ b/lldb/source/Plugins/Platform/Windows/PlatformWindows.h
@@ -80,6 +80,14 @@ class PlatformWindows : public RemoteAwarePlatform {
   size_t GetSoftwareBreakpointTrapOpcode(Target &target,
                                          BreakpointSite *bp_site) override;
 
+  /// Set the current console's code page to UTF-8 and store the previous
+  /// codepage in \a g_prev_console_cp.
+  static void SetConsoleCodePage();
+
+  /// Reset the current console's code page to the value stored
+  /// in \a g_prev_console_cp if any.
+  static void ResetConsoleCodePage();
+
   std::vector<ArchSpec> m_supported_architectures;
 
 private:

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to