Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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