Skip to content

Commit 2c16cbe

Browse files
[lldb][windows] add Windows Virtual Console support
1 parent 928393b commit 2c16cbe

File tree

18 files changed

+506
-150
lines changed

18 files changed

+506
-150
lines changed

lldb/include/lldb/Host/ProcessLaunchInfo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,9 @@ class ProcessLaunchInfo : public ProcessInfo {
118118

119119
bool MonitorProcess() const;
120120

121-
PseudoTerminal &GetPTY() { return *m_pty; }
121+
PseudoTerminal &GetPTY() const { return *m_pty; }
122+
123+
std::shared_ptr<PseudoTerminal> GetPTYSP() const { return m_pty; }
122124

123125
void SetLaunchEventData(const char *data) { m_event_data.assign(data); }
124126

lldb/include/lldb/Host/PseudoTerminal.h

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@ class PseudoTerminal {
3535

3636
/// Destructor
3737
///
38-
/// The destructor will close the primary and secondary file descriptors if
39-
/// they are valid and ownership has not been released using one of: @li
40-
/// PseudoTerminal::ReleasePrimaryFileDescriptor() @li
41-
/// PseudoTerminal::ReleaseSaveFileDescriptor()
42-
~PseudoTerminal();
38+
/// The destructor will close the primary and secondary file
39+
/// descriptor/HANDLEs if they are valid and ownership has not been released
40+
/// using PseudoTerminal::Close().
41+
virtual ~PseudoTerminal();
42+
43+
/// Close all the file descriptors or Handles of the PseudoTerminal if they
44+
/// are valid.
45+
virtual void Close();
4346

4447
/// Close the primary file descriptor if it is valid.
4548
void ClosePrimaryFileDescriptor();
@@ -59,8 +62,7 @@ class PseudoTerminal {
5962
///
6063
/// This class will close the file descriptors for the primary/secondary when
6164
/// the destructor is called. The file handles can be released using either:
62-
/// @li PseudoTerminal::ReleasePrimaryFileDescriptor() @li
63-
/// PseudoTerminal::ReleaseSaveFileDescriptor()
65+
/// @li PseudoTerminal::ReleasePrimaryFileDescriptor()
6466
///
6567
/// \return
6668
/// \b Parent process: a child process ID that is greater
@@ -82,6 +84,16 @@ class PseudoTerminal {
8284
/// \see PseudoTerminal::ReleasePrimaryFileDescriptor()
8385
int GetPrimaryFileDescriptor() const;
8486

87+
/// The primary HANDLE accessor.
88+
///
89+
/// This object retains ownership of the primary HANDLE when this
90+
/// accessor is used.
91+
///
92+
/// \return
93+
/// The primary HANDLE, or INVALID_HANDLE_VALUE if the primary HANDLE is
94+
/// not currently valid.
95+
virtual void *GetPrimaryHandle() const { return ((void *)(long long)-1); };
96+
8597
/// The secondary file descriptor accessor.
8698
///
8799
/// This object retains ownership of the secondary file descriptor when this
@@ -96,6 +108,8 @@ class PseudoTerminal {
96108
/// \see PseudoTerminal::ReleaseSecondaryFileDescriptor()
97109
int GetSecondaryFileDescriptor() const;
98110

111+
virtual void *GetSecondaryHandle() const { return ((void *)(long long)-1); };
112+
99113
/// Get the name of the secondary pseudo terminal.
100114
///
101115
/// A primary pseudo terminal should already be valid prior to
@@ -105,7 +119,17 @@ class PseudoTerminal {
105119
/// The name of the secondary pseudo terminal.
106120
///
107121
/// \see PseudoTerminal::OpenFirstAvailablePrimary()
108-
std::string GetSecondaryName() const;
122+
virtual std::string GetSecondaryName() const;
123+
124+
/// The underlying Windows Pseudo Terminal HANDLE's accessor.
125+
///
126+
/// This object retains ownership of the ConPTY's HANDLE when this
127+
/// accessor is used.
128+
///
129+
/// \return
130+
/// The primary HANDLE, or INVALID_HANDLE_VALUE if the primary HANDLE is
131+
/// not currently valid.
132+
virtual void *GetPseudoTerminalHandle() { return ((void *)(long long)-1); };
109133

110134
/// Open the first available pseudo terminal.
111135
///
@@ -126,7 +150,7 @@ class PseudoTerminal {
126150
///
127151
/// \see PseudoTerminal::GetPrimaryFileDescriptor() @see
128152
/// PseudoTerminal::ReleasePrimaryFileDescriptor()
129-
llvm::Error OpenFirstAvailablePrimary(int oflag);
153+
virtual llvm::Error OpenFirstAvailablePrimary(int oflag);
130154

131155
/// Open the secondary for the current primary pseudo terminal.
132156
///
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef liblldb_Host_Windows_PseudoTerminalWindows_H_
10+
#define liblldb_Host_Windows_PseudoTerminalWindows_H_
11+
12+
#include "lldb/Host/PseudoTerminal.h"
13+
#include "lldb/Host/windows/windows.h"
14+
15+
namespace lldb_private {
16+
17+
class PseudoTerminalWindows : public PseudoTerminal {
18+
19+
public:
20+
void Close() override;
21+
22+
HPCON GetPseudoTerminalHandle() override { return m_conpty_handle; };
23+
24+
HANDLE GetPrimaryHandle() const override { return m_conpty_output; };
25+
26+
HANDLE GetSecondaryHandle() const override { return m_conpty_input; };
27+
28+
std::string GetSecondaryName() const override { return ""; };
29+
30+
llvm::Error OpenFirstAvailablePrimary(int oflag) override;
31+
32+
protected:
33+
HANDLE m_conpty_handle = INVALID_HANDLE_VALUE;
34+
HANDLE m_conpty_output = INVALID_HANDLE_VALUE;
35+
HANDLE m_conpty_input = INVALID_HANDLE_VALUE;
36+
};
37+
}; // namespace lldb_private
38+
39+
#endif // liblldb_Host_Windows_PseudoTerminalWindows_H_

lldb/include/lldb/Host/windows/windows.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
#ifndef LLDB_lldb_windows_h_
1010
#define LLDB_lldb_windows_h_
1111

12-
#define NTDDI_VERSION NTDDI_VISTA
12+
#define NTDDI_VERSION NTDDI_WIN10_RS5
1313
#undef _WIN32_WINNT // undef a previous definition to avoid warning
14-
#define _WIN32_WINNT _WIN32_WINNT_VISTA
14+
#define _WIN32_WINNT _WIN32_WINNT_WIN10
1515
#define WIN32_LEAN_AND_MEAN
1616
#define NOGDI
1717
#undef NOMINMAX // undef a previous definition to avoid warning

lldb/include/lldb/Target/Process.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,8 +2534,36 @@ void PruneThreadPlans();
25342534

25352535
void CalculateExecutionContext(ExecutionContext &exe_ctx) override;
25362536

2537+
/// Associates a file descriptor with the process's STDIO handling
2538+
/// and configures an asynchronous reading of that descriptor.
2539+
///
2540+
/// This method installs a ConnectionFileDescriptor for the passed file
2541+
/// descriptor and starts a dedicated read thread. If the read thread starts
2542+
/// successfully, the method also ensures that an IOHandlerProcessSTDIO is
2543+
/// created to manage user input to the process.
2544+
///
2545+
/// The descriptor's ownership is transferred to the underlying
2546+
/// ConnectionFileDescriptor.
2547+
///
2548+
/// \param[in] fd
2549+
/// The file descriptor to use for process STDIO communication. It's
2550+
/// assumed to be valid and will be managed by the newly created
2551+
/// connection.
2552+
///
2553+
/// \see lldb_private::Process::STDIOReadThreadBytesReceived()
2554+
/// \see lldb_private::IOHandlerProcessSTDIO
2555+
/// \see lldb_private::ConnectionFileDescriptor
25372556
void SetSTDIOFileDescriptor(int file_descriptor);
25382557

2558+
/// Windows equivalent of Process::SetSTDIOFileDescriptor, with a
2559+
/// PseudoTerminalWindows instead of a file descriptor.
2560+
///
2561+
/// \param pty
2562+
/// The PseudoTerminal to use for process STDIO communication. It is not
2563+
/// managed by the created read thread.
2564+
virtual void
2565+
SetPseudoTerminalHandle(const std::shared_ptr<PseudoTerminal> &pty) {};
2566+
25392567
// Add a permanent region of memory that should never be read or written to.
25402568
// This can be used to ensure that memory reads or writes to certain areas of
25412569
// memory never end up being sent to the DoReadMemory or DoWriteMemory

lldb/source/Host/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
7575
windows/MainLoopWindows.cpp
7676
windows/PipeWindows.cpp
7777
windows/ProcessLauncherWindows.cpp
78+
windows/PseudoTerminalWindows.cpp
7879
windows/ProcessRunLock.cpp
7980
)
8081
else()

lldb/source/Host/common/ProcessLaunchInfo.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
#include "llvm/Support/ConvertUTF.h"
2121
#include "llvm/Support/FileSystem.h"
2222

23-
#if !defined(_WIN32)
23+
#ifdef _WIN32
24+
#include "lldb/Host/windows/PseudoTerminalWindows.h"
25+
#else
2426
#include <climits>
2527
#endif
2628

@@ -31,7 +33,12 @@ using namespace lldb_private;
3133

3234
ProcessLaunchInfo::ProcessLaunchInfo()
3335
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(0),
34-
m_file_actions(), m_pty(new PseudoTerminal), m_monitor_callback(nullptr) {
36+
m_file_actions(), m_monitor_callback(nullptr) {
37+
#ifdef _WIN32
38+
m_pty = std::make_shared<PseudoTerminalWindows>();
39+
#else
40+
m_pty = std::make_shared<PseudoTerminal>();
41+
#endif
3542
}
3643

3744
ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
@@ -40,7 +47,13 @@ ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec,
4047
const FileSpec &working_directory,
4148
uint32_t launch_flags)
4249
: ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(launch_flags),
43-
m_file_actions(), m_pty(new PseudoTerminal) {
50+
m_file_actions() {
51+
#ifdef _WIN32
52+
m_pty = std::make_shared<PseudoTerminalWindows>();
53+
#else
54+
m_pty = std::make_shared<PseudoTerminal>();
55+
#endif
56+
4457
if (stdin_file_spec) {
4558
FileAction file_action;
4659
const bool read = true;

lldb/source/Host/common/PseudoTerminal.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "lldb/Host/PseudoTerminal.h"
1010
#include "lldb/Host/Config.h"
1111
#include "lldb/Host/FileSystem.h"
12+
#include "lldb/Host/windows/windows.h"
1213
#include "llvm/Support/Errc.h"
1314
#include "llvm/Support/Errno.h"
1415
#include <cassert>
@@ -29,16 +30,11 @@
2930

3031
using namespace lldb_private;
3132

32-
// PseudoTerminal constructor
3333
PseudoTerminal::PseudoTerminal() = default;
3434

35-
// Destructor
36-
//
37-
// The destructor will close the primary and secondary file descriptors if they
38-
// are valid and ownership has not been released using the
39-
// ReleasePrimaryFileDescriptor() or the ReleaseSaveFileDescriptor() member
40-
// functions.
41-
PseudoTerminal::~PseudoTerminal() {
35+
PseudoTerminal::~PseudoTerminal() { Close(); }
36+
37+
void PseudoTerminal::Close() {
4238
ClosePrimaryFileDescriptor();
4339
CloseSecondaryFileDescriptor();
4440
}

0 commit comments

Comments
 (0)