Author: Charles Zablit Date: 2025-08-19T14:52:29+01:00 New Revision: f55dc0824ebcf546b1d34a5102021c15101e4d3b
URL: https://github.com/llvm/llvm-project/commit/f55dc0824ebcf546b1d34a5102021c15101e4d3b DIFF: https://github.com/llvm/llvm-project/commit/f55dc0824ebcf546b1d34a5102021c15101e4d3b.diff LOG: [lldb][windows] use Windows APIs to print to the console (#149493) This patch uses the Windows APIs to print to the Windows Console, through `llvm::raw_fd_ostream`. 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 patch downstream](https://github.com/swiftlang/swift/pull/40632/files#diff-e948e4bd7a601e3ca82d596058ccb39326459a4751470eec4d393adeaf516977R37-R38). rdar://156064500 Added: Modified: lldb/include/lldb/Host/File.h lldb/source/Host/common/File.cpp Removed: ################################################################################ diff --git a/lldb/include/lldb/Host/File.h b/lldb/include/lldb/Host/File.h index 9e2d0abe0b1af..7402a2231735a 100644 --- a/lldb/include/lldb/Host/File.h +++ b/lldb/include/lldb/Host/File.h @@ -382,15 +382,11 @@ class NativeFile : public File { Unowned = false, }; - NativeFile() : m_descriptor(kInvalidDescriptor), m_stream(kInvalidStream) {} + NativeFile(); - NativeFile(FILE *fh, bool transfer_ownership) - : m_descriptor(kInvalidDescriptor), m_own_descriptor(false), m_stream(fh), - m_options(), m_own_stream(transfer_ownership) {} + NativeFile(FILE *fh, bool transfer_ownership); - NativeFile(int fd, OpenOptions options, bool transfer_ownership) - : m_descriptor(fd), m_own_descriptor(transfer_ownership), - m_stream(kInvalidStream), m_options(options), m_own_stream(false) {} + NativeFile(int fd, OpenOptions options, bool transfer_ownership); ~NativeFile() override { Close(); } @@ -444,17 +440,19 @@ class NativeFile : public File { return ValueGuard(m_stream_mutex, StreamIsValidUnlocked()); } - int m_descriptor; + int m_descriptor = kInvalidDescriptor; bool m_own_descriptor = false; mutable std::mutex m_descriptor_mutex; - FILE *m_stream; + FILE *m_stream = kInvalidStream; mutable std::mutex m_stream_mutex; OpenOptions m_options{}; bool m_own_stream = false; std::mutex offset_access_mutex; + bool is_windows_console = false; + private: NativeFile(const NativeFile &) = delete; const NativeFile &operator=(const NativeFile &) = delete; diff --git a/lldb/source/Host/common/File.cpp b/lldb/source/Host/common/File.cpp index 23b6dc9fe850d..8cbbd7a5e14c7 100644 --- a/lldb/source/Host/common/File.cpp +++ b/lldb/source/Host/common/File.cpp @@ -36,6 +36,7 @@ #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Process.h" +#include "llvm/Support/raw_ostream.h" using namespace lldb; using namespace lldb_private; @@ -247,6 +248,32 @@ uint32_t File::GetPermissions(Status &error) const { return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); } +NativeFile::NativeFile() = default; + +NativeFile::NativeFile(FILE *fh, bool transfer_ownership) + : m_stream(fh), m_own_stream(transfer_ownership) { +#ifdef _WIN32 + // In order to properly display non ASCII characters in Windows, we need to + // use Windows APIs to print to the console. This is only required if the + // stream outputs to a console. + int fd = _fileno(fh); + is_windows_console = + ::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR; +#endif +} + +NativeFile::NativeFile(int fd, OpenOptions options, bool transfer_ownership) + : m_descriptor(fd), m_own_descriptor(transfer_ownership), + m_options(options) { +#ifdef _WIN32 + // In order to properly display non ASCII characters in Windows, we need to + // use Windows APIs to print to the console. This is only required if the + // file outputs to a console. + is_windows_console = + ::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR; +#endif +} + bool NativeFile::IsValid() const { std::scoped_lock<std::mutex, std::mutex> lock(m_descriptor_mutex, m_stream_mutex); return DescriptorIsValidUnlocked() || StreamIsValidUnlocked(); @@ -618,6 +645,12 @@ Status NativeFile::Write(const void *buf, size_t &num_bytes) { ssize_t bytes_written = -1; if (ValueGuard descriptor_guard = DescriptorIsValid()) { +#ifdef _WIN32 + if (is_windows_console) { + llvm::raw_fd_ostream(m_descriptor, false).write((char *)buf, num_bytes); + return error; + } +#endif bytes_written = llvm::sys::RetryAfterSignal(-1, ::write, m_descriptor, buf, num_bytes); if (bytes_written == -1) { @@ -629,6 +662,13 @@ Status NativeFile::Write(const void *buf, size_t &num_bytes) { } if (ValueGuard stream_guard = StreamIsValid()) { +#ifdef _WIN32 + if (is_windows_console) { + llvm::raw_fd_ostream(_fileno(m_stream), false) + .write((char *)buf, num_bytes); + return error; + } +#endif bytes_written = ::fwrite(buf, 1, num_bytes, m_stream); if (bytes_written == 0) { _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits