diff --git a/lldb/test/API/tools/lldb-vscode/disconnect/Makefile b/lldb/test/API/tools/lldb-vscode/disconnect/Makefile new file mode 100644 --- /dev/null +++ b/lldb/test/API/tools/lldb-vscode/disconnect/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-vscode/disconnect/TestVSCode_disconnect.py b/lldb/test/API/tools/lldb-vscode/disconnect/TestVSCode_disconnect.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/tools/lldb-vscode/disconnect/TestVSCode_disconnect.py @@ -0,0 +1,68 @@ +""" +Test lldb-vscode disconnect request +""" + + +import unittest2 +import vscode +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil +import lldbvscode_testcase +import subprocess +import time +import os + + +class TestVSCode_launch(lldbvscode_testcase.VSCodeTestCaseBase): + + mydir = TestBase.compute_mydir(__file__) + source = 'main.c' + + def disconnect_and_check_no_output(self): + self.vscode.request_disconnect() + # verify we didn't get any input after disconnect + time.sleep(2) + output = self.get_stdout() + self.assertTrue(output is None or len(output) == 0) + + @skipIfWindows + @skipIfRemote + def test_launch(self): + """ + This test launches a process that would output some text to the stdout + if we let it run after disconnection. + """ + program = self.getBuildArtifact("a.out") + self.build_and_launch(program) + + self.set_source_breakpoints(self.source, [line_number(self.source, '// breakpoint 1')]) + self.continue_to_next_stop() + + self.disconnect_and_check_no_output() + + + @skipIfWindows + @skipIfRemote + def test_attach(self): + """ + This test attaches to a running process that would output some text to the stdout + if we let it run after disconnection. + """ + self.build_and_create_debug_adaptor() + program = self.getBuildArtifact("a.out") + + self.process = subprocess.Popen([program, "--attach"], + universal_newlines=True, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + self.attach(pid=self.process.pid) + + self.set_source_breakpoints(self.source, [line_number(self.source, '// breakpoint 2')]) + + self.process.stdin.write("42 ") + self.process.stdin.flush() + self.continue_to_next_stop() + + self.disconnect_and_check_no_output() diff --git a/lldb/test/API/tools/lldb-vscode/disconnect/main.c b/lldb/test/API/tools/lldb-vscode/disconnect/main.c new file mode 100644 --- /dev/null +++ b/lldb/test/API/tools/lldb-vscode/disconnect/main.c @@ -0,0 +1,21 @@ +#include + +void for_launch() { + int x = 0; // breakpoint 1 + printf("%d\n", x); +} + +void for_attach() { + int x; + // We wait for a signal to proceed + scanf("%d", &x); + printf("%d\n", x); // breakpoint 2 +} + +int main(int argc, char **args) { + if (argc == 1) + for_launch(); + else + for_attach(); + return 0; +} diff --git a/lldb/tools/lldb-vscode/VSCode.h b/lldb/tools/lldb-vscode/VSCode.h --- a/lldb/tools/lldb-vscode/VSCode.h +++ b/lldb/tools/lldb-vscode/VSCode.h @@ -89,6 +89,7 @@ lldb::tid_t focus_tid; bool sent_terminated_event; bool stop_at_entry; + bool is_attach; // Keep track of the last stop thread index IDs as threads won't go away // unless we send a "thread" event to indicate the thread exited. llvm::DenseSet thread_ids; diff --git a/lldb/tools/lldb-vscode/lldb-vscode.cpp b/lldb/tools/lldb-vscode/lldb-vscode.cpp --- a/lldb/tools/lldb-vscode/lldb-vscode.cpp +++ b/lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -514,6 +514,7 @@ // }] // } void request_attach(const llvm::json::Object &request) { + g_vsc.is_attach = true; llvm::json::Object response; lldb::SBError error; FillResponse(request, response); @@ -769,7 +770,9 @@ FillResponse(request, response); auto arguments = request.getObject("arguments"); - bool terminateDebuggee = GetBoolean(arguments, "terminateDebuggee", false); + bool defaultTerminateDebuggee = g_vsc.is_attach ? false : true; + bool terminateDebuggee = + GetBoolean(arguments, "terminateDebuggee", defaultTerminateDebuggee); lldb::SBProcess process = g_vsc.target.GetProcess(); auto state = process.GetState(); @@ -1357,6 +1360,7 @@ // }] // } void request_launch(const llvm::json::Object &request) { + g_vsc.is_attach = false; llvm::json::Object response; lldb::SBError error; FillResponse(request, response);