Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lldb/include/lldb/Host/windows/ProcessLauncherWindows.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ class ProcessLauncherWindows : public ProcessLauncher {
HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info,
Status &error) override;

protected:
/// Get the list of Windows handles that should be inherited by the child
/// process and update `STARTUPINFOEXW` with the handle list.
///
Expand Down
4 changes: 3 additions & 1 deletion lldb/packages/Python/lldbsuite/test/dotest.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,9 @@ def setupSysPath():

lldbDir = os.path.dirname(lldbtest_config.lldbExec)

lldbDAPExec = os.path.join(lldbDir, "lldb-dap")
lldbDAPExec = os.path.join(
lldbDir, "lldb-dap.exe" if sys.platform == "win32" else "lldb-dap"
)
if is_exe(lldbDAPExec):
os.environ["LLDBDAP_EXEC"] = lldbDAPExec

Expand Down
4 changes: 1 addition & 3 deletions lldb/source/Host/windows/ProcessLauncherWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ GetFlattenedWindowsCommandStringW(llvm::ArrayRef<const char *> args) {
if (args.empty())
return L"";

std::vector<llvm::StringRef> args_ref;
for (int i = 0; args[i] != nullptr; ++i)
args_ref.push_back(args[i]);
std::vector<llvm::StringRef> args_ref(args.begin(), args.end());

return llvm::sys::flattenWindowsCommandLine(args_ref);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def verify_stopped_on_entry(self, stopped_events: List[Dict[str, Any]]):
self.assertEqual(seen_stopped_event, 1, "expect only one stopped entry event.")

@skipIfAsan
@skipIfWindows
@expectedFailureWindows
@skipIf(oslist=["linux"], archs=["arm$"]) # Always times out on buildbot
def test_basic_functionality(self):
"""
Expand Down Expand Up @@ -83,7 +83,7 @@ def test_basic_functionality(self):
self.continue_to_exit()

@skipIfAsan
@skipIfWindows
@expectedFailureWindows
@skipIf(oslist=["linux"], archs=["arm$"]) # Always times out on buildbot
def test_stopOnEntry(self):
"""
Expand Down
249 changes: 160 additions & 89 deletions lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Test lldb-dap runInTerminal reverse request
"""

from contextlib import contextmanager
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import line_number
import lldbdap_testcase
Expand All @@ -10,25 +11,101 @@
import json


@contextmanager
def fifo(*args, **kwargs):
if sys.platform == "win32":
import ctypes

comm_file = r"\\.\pipe\lldb-dap-run-in-terminal-comm"
PIPE_ACCESS_DUPLEX = 0x00000003
PIPE_TYPE_MESSAGE = 0x00000004
PIPE_READMODE_MESSAGE = 0x00000002
PIPE_WAIT = 0x00000000
PIPE_UNLIMITED_INSTANCES = 255
kernel32 = ctypes.windll.kernel32

pipe = kernel32.CreateNamedPipeW(
comm_file,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
4096,
4096,
0,
None,
)
else:
comm_file = os.path.join(kwargs["directory"], "comm-file")
pipe = None
os.mkfifo(comm_file)

try:
yield comm_file, pipe
finally:
if pipe is not None:
kernel32.DisconnectNamedPipe(pipe)
kernel32.CloseHandle(pipe)


def read_pipe_message(pipe):
import ctypes

ERROR_MORE_DATA = 234
kernel32 = ctypes.windll.kernel32
buffer = b""
while True:
chunk = ctypes.create_string_buffer(4096)
bytes_read = ctypes.wintypes.DWORD()
success = kernel32.ReadFile(pipe, chunk, 4096, ctypes.byref(bytes_read), None)
buffer += chunk.raw[: bytes_read.value]
if success:
break
if ctypes.GetLastError() != ERROR_MORE_DATA:
break
return buffer.decode()


@skipIfBuildType(["debug"])
class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
def read_pid_message(self, fifo_file):
with open(fifo_file, "r") as file:
self.assertIn("pid", file.readline())
def read_pid_message(self, fifo_file, pipe):
if sys.platform == "win32":
import ctypes

ctypes.windll.kernel32.ConnectNamedPipe(pipe, None)
self.assertIn("pid", read_pipe_message(pipe))
else:
with open(fifo_file, "r") as file:
self.assertIn("pid", file.readline())

@staticmethod
def send_did_attach_message(fifo_file):
with open(fifo_file, "w") as file:
file.write(json.dumps({"kind": "didAttach"}) + "\n")
def send_did_attach_message(fifo_file, pipe=None):
message = json.dumps({"kind": "didAttach"}) + "\n"
if sys.platform == "win32":
import ctypes

kernel32 = ctypes.windll.kernel32
bytes_written = ctypes.wintypes.DWORD()
kernel32.ConnectNamedPipe(pipe, None)
kernel32.WriteFile(
pipe, message.encode(), len(message), ctypes.byref(bytes_written), None
)
else:
with open(fifo_file, "w") as file:
file.write(message)

@staticmethod
def read_error_message(fifo_file):
with open(fifo_file, "r") as file:
return file.readline()
def read_error_message(fifo_file, pipe=None):
if sys.platform == "win32":
import ctypes

ctypes.windll.kernel32.ConnectNamedPipe(pipe, None)
return read_pipe_message(pipe)
else:
with open(fifo_file, "r") as file:
return file.readline()

@skipIfLinux # FIXME: doesn't seem to work on Ubuntu 16.04.
@skipIfAsan
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminal(self):
"""
Expand Down Expand Up @@ -76,7 +153,6 @@ def test_runInTerminal(self):
self.continue_to_exit()

@skipIfAsan
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminalWithObjectEnv(self):
"""
Expand All @@ -101,7 +177,6 @@ def test_runInTerminalWithObjectEnv(self):
self.continue_to_exit()

@skipIfLinux # FIXME: doesn't seem to work on Ubuntu 16.04.
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminalInvalidTarget(self):
self.build_and_create_debug_adapter()
Expand All @@ -119,7 +194,6 @@ def test_runInTerminalInvalidTarget(self):
)

@skipIfLinux # FIXME: doesn't seem to work on Ubuntu 16.04.
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_missingArgInRunInTerminalLauncher(self):
proc = subprocess.run(
Expand All @@ -133,99 +207,96 @@ def test_missingArgInRunInTerminalLauncher(self):
)

@skipIfLinux # FIXME: doesn't seem to work on Ubuntu 16.04.
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self):
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)

proc = subprocess.Popen(
[
self.lldbDAPExec,
"--comm-file",
comm_file,
"--launch-target",
"INVALIDPROGRAM",
],
universal_newlines=True,
stderr=subprocess.PIPE,
)

self.read_pid_message(comm_file)
self.send_did_attach_message(comm_file)
self.assertIn("No such file or directory", self.read_error_message(comm_file))

_, stderr = proc.communicate()
self.assertIn("No such file or directory", stderr)
with fifo(directory=self.getBuildDir()) as (comm_file, pipe):
proc = subprocess.Popen(
[
self.lldbDAPExec,
"--comm-file",
comm_file,
"--launch-target",
"INVALIDPROGRAM",
],
universal_newlines=True,
stderr=subprocess.PIPE,
)
if sys.platform == "win32":
_, stderr = proc.communicate()
self.assertIn("Failed to launch target process", stderr)
else:
self.read_pid_message(comm_file, pipe)
self.send_did_attach_message(comm_file, pipe)
self.assertIn(
"No such file or directory",
self.read_error_message(comm_file, pipe),
)

_, stderr = proc.communicate()
self.assertIn("No such file or directory", stderr)

@skipIfLinux # FIXME: doesn't seem to work on Ubuntu 16.04.
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self):
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)

proc = subprocess.Popen(
[
self.lldbDAPExec,
"--comm-file",
comm_file,
"--launch-target",
"echo",
"foo",
],
universal_newlines=True,
stdout=subprocess.PIPE,
)

self.read_pid_message(comm_file)
self.send_did_attach_message(comm_file)
with fifo(directory=self.getBuildDir()) as (comm_file, pipe):
proc = subprocess.Popen(
[
self.lldbDAPExec,
"--comm-file",
comm_file,
"--launch-target",
"echo",
"foo",
],
universal_newlines=True,
stdout=subprocess.PIPE,
)

self.read_pid_message(comm_file, pipe)
self.send_did_attach_message(comm_file, pipe)

stdout, _ = proc.communicate()

stdout, _ = proc.communicate()
self.assertIn("foo", stdout)

@skipIfLinux # FIXME: doesn't seem to work on Ubuntu 16.04.
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self):
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)
with fifo(directory=self.getBuildDir()) as (comm_file, pipe):
proc = subprocess.Popen(
[self.lldbDAPExec, "--comm-file", comm_file, "--launch-target", "env"],
universal_newlines=True,
stdout=subprocess.PIPE,
env={**os.environ, "FOO": "BAR"},
)

proc = subprocess.Popen(
[self.lldbDAPExec, "--comm-file", comm_file, "--launch-target", "env"],
universal_newlines=True,
stdout=subprocess.PIPE,
env={**os.environ, "FOO": "BAR"},
)
self.read_pid_message(comm_file, pipe)
self.send_did_attach_message(comm_file, pipe)

self.read_pid_message(comm_file)
self.send_did_attach_message(comm_file)
stdout, _ = proc.communicate()

stdout, _ = proc.communicate()
self.assertIn("FOO=BAR", stdout)

@skipIfLinux # FIXME: doesn't seem to work on Ubuntu 16.04.
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_NonAttachedRunInTerminalLauncher(self):
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)

proc = subprocess.Popen(
[
self.lldbDAPExec,
"--comm-file",
comm_file,
"--launch-target",
"echo",
"foo",
],
universal_newlines=True,
stderr=subprocess.PIPE,
env={**os.environ, "LLDB_DAP_RIT_TIMEOUT_IN_MS": "1000"},
)

self.read_pid_message(comm_file)

_, stderr = proc.communicate()
self.assertIn("Timed out trying to get messages from the debug adapter", stderr)
with fifo(directory=self.getBuildDir()) as (comm_file, pipe):
proc = subprocess.Popen(
[
self.lldbDAPExec,
"--comm-file",
comm_file,
"--launch-target",
"echo",
"foo",
],
universal_newlines=True,
stderr=subprocess.PIPE,
env={**os.environ, "LLDB_DAP_RIT_TIMEOUT_IN_MS": "1000"},
)

self.read_pid_message(comm_file, pipe)

_, stderr = proc.communicate()

self.assertIn("Timed out trying to get messages from the debug adapter", stderr)
Loading