wallace updated this revision to Diff 271542.
wallace added a comment.

.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81978/new/

https://reviews.llvm.org/D81978

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py
  lldb/test/API/tools/lldb-vscode/launch/TestVSCode_launch.py
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===================================================================
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -174,6 +174,7 @@
 void SendTerminatedEvent() {
   if (!g_vsc.sent_terminated_event) {
     g_vsc.sent_terminated_event = true;
+    g_vsc.RunTerminateCommands();
     // Send a "terminated" event
     llvm::json::Object event(CreateEventObject("terminated"));
     g_vsc.SendJSON(llvm::json::Value(std::move(event)));
@@ -530,6 +531,7 @@
   g_vsc.pre_run_commands = GetStrings(arguments, "preRunCommands");
   g_vsc.stop_commands = GetStrings(arguments, "stopCommands");
   g_vsc.exit_commands = GetStrings(arguments, "exitCommands");
+  g_vsc.terminate_commands = GetStrings(arguments, "terminateCommands");
   auto attachCommands = GetStrings(arguments, "attachCommands");
   llvm::StringRef core_file = GetString(arguments, "coreFile");
   g_vsc.stop_at_entry =
@@ -775,7 +777,6 @@
       GetBoolean(arguments, "terminateDebuggee", defaultTerminateDebuggee);
   lldb::SBProcess process = g_vsc.target.GetProcess();
   auto state = process.GetState();
-
   switch (state) {
   case lldb::eStateInvalid:
   case lldb::eStateUnloaded:
@@ -797,8 +798,8 @@
     g_vsc.debugger.SetAsync(true);
     break;
   }
-  g_vsc.SendJSON(llvm::json::Value(std::move(response)));
   SendTerminatedEvent();
+  g_vsc.SendJSON(llvm::json::Value(std::move(response)));
   if (g_vsc.event_thread.joinable()) {
     g_vsc.broadcaster.BroadcastEventByType(eBroadcastBitStopEventThread);
     g_vsc.event_thread.join();
@@ -1368,6 +1369,7 @@
   g_vsc.pre_run_commands = GetStrings(arguments, "preRunCommands");
   g_vsc.stop_commands = GetStrings(arguments, "stopCommands");
   g_vsc.exit_commands = GetStrings(arguments, "exitCommands");
+  g_vsc.terminate_commands = GetStrings(arguments, "terminateCommands");
   auto launchCommands = GetStrings(arguments, "launchCommands");
   g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false);
   const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
Index: lldb/tools/lldb-vscode/VSCode.h
===================================================================
--- lldb/tools/lldb-vscode/VSCode.h
+++ lldb/tools/lldb-vscode/VSCode.h
@@ -86,6 +86,7 @@
   std::vector<std::string> pre_run_commands;
   std::vector<std::string> exit_commands;
   std::vector<std::string> stop_commands;
+  std::vector<std::string> terminate_commands;
   lldb::tid_t focus_tid;
   bool sent_terminated_event;
   bool stop_at_entry;
@@ -133,6 +134,7 @@
   void RunPreRunCommands();
   void RunStopCommands();
   void RunExitCommands();
+  void RunTerminateCommands();
 
   /// Create a new SBTarget object from the given request arguments.
   /// \param[in] arguments
Index: lldb/tools/lldb-vscode/VSCode.cpp
===================================================================
--- lldb/tools/lldb-vscode/VSCode.cpp
+++ lldb/tools/lldb-vscode/VSCode.cpp
@@ -309,6 +309,10 @@
   RunLLDBCommands("Running exitCommands:", exit_commands);
 }
 
+void VSCode::RunTerminateCommands() {
+  RunLLDBCommands("Running terminateCommands:", terminate_commands);
+}
+
 lldb::SBTarget VSCode::CreateTargetFromArguments(
     const llvm::json::Object &arguments,
     lldb::SBError &error) {
Index: lldb/tools/lldb-vscode/README.md
===================================================================
--- lldb/tools/lldb-vscode/README.md
+++ lldb/tools/lldb-vscode/README.md
@@ -16,14 +16,14 @@
 
 The `lldb-vscode` tool creates a command line tool that implements the [Visual
 Studio Code Debug API](https://code.visualstudio.com/docs/extensionAPI/api-debugging).
-It can be installed as an extension for the Visual Studio Code and Nuclide IDE. 
+It can be installed as an extension for the Visual Studio Code and Nuclide IDE.
 The protocol is easy to run remotely and also can allow other tools and IDEs to
-get a full featured debugger with a well defined protocol. 
+get a full featured debugger with a well defined protocol.
 
 # Installation for Visual Studio Code
 
 Installing the plug-in involves creating a directory in the `~/.vscode/extensions` folder and copying the package.json file that is in the same directory as this
-documentation into it, and copying to symlinking a lldb-vscode binary into 
+documentation into it, and copying to symlinking a lldb-vscode binary into
 the `bin` directory inside the plug-in directory.
 
 If you want to make a stand alone plug-in that you can send to others on unix systems:
@@ -86,6 +86,7 @@
 |**preRunCommands** |[string]| | LLDB commands executed just before launching after the LLDB target has been created. Commands and command output will be sent to the debugger console when they are executed.
 |**stopCommands**   |[string]| | LLDB commands executed just after each stop. Commands and command output will be sent to the debugger console when they are executed.
 |**exitCommands**   |[string]| | LLDB commands executed when the program exits. Commands and command output will be sent to the debugger console when they are executed.
+|**terminateCommands** |[string]| | LLDB commands executed when the debugging session ends. Commands and command output will be sent to the debugger console when they are executed.
 |**sourceMap**      |[string[2]]| | Specify an array of path re-mappings. Each element in the array must be a two element array containing a source and destination pathname.
 |**debuggerRoot**   | string| |Specify a working directory to use when launching lldb-vscode. If the debug information in your executable contains relative paths, this option can be used so that `lldb-vscode` can find source files and object files that have relative paths.
 
@@ -112,6 +113,7 @@
 |**preRunCommands** |[string]| | LLDB commands executed just before launching after the LLDB target has been created. Commands and command output will be sent to the debugger console when they are executed.
 |**stopCommands**   |[string]| | LLDB commands executed just after each stop. Commands and command output will be sent to the debugger console when they are executed.
 |**exitCommands**   |[string]| | LLDB commands executed when the program exits. Commands and command output will be sent to the debugger console when they are executed.
+|**terminateCommands** |[string]| | LLDB commands executed when the debugging session ends. Commands and command output will be sent to the debugger console when they are executed.
 |**attachCommands** |[string]| | LLDB commands that will be executed after **preRunCommands** which take place of the code that normally does the attach. The commands can create a new target and attach or launch it however desired. This allows custom launch and attach configurations. Core files can use `target create --core /path/to/core` to attach to core files.
 
 
Index: lldb/test/API/tools/lldb-vscode/launch/TestVSCode_launch.py
===================================================================
--- lldb/test/API/tools/lldb-vscode/launch/TestVSCode_launch.py
+++ lldb/test/API/tools/lldb-vscode/launch/TestVSCode_launch.py
@@ -294,8 +294,9 @@
     @skipIfRemote
     def test_commands(self):
         '''
-            Tests the "initCommands", "preRunCommands", "stopCommands" and
-            "exitCommands" that can be passed during launch.
+            Tests the "initCommands", "preRunCommands", "stopCommands",
+            "terminateCommands" and "exitCommands" that can be passed during
+            launch.
 
             "initCommands" are a list of LLDB commands that get executed
             before the targt is created.
@@ -305,17 +306,21 @@
             time the program stops.
             "exitCommands" are a list of LLDB commands that get executed when
             the process exits
+            "terminateCommands" are a list of LLDB commands that get executed when
+            the debugger session terminates.
         '''
         program = self.getBuildArtifact("a.out")
         initCommands = ['target list', 'platform list']
         preRunCommands = ['image list a.out', 'image dump sections a.out']
         stopCommands = ['frame variable', 'bt']
         exitCommands = ['expr 2+3', 'expr 3+4']
+        terminateCommands = ['expr 4+2']
         self.build_and_launch(program,
                               initCommands=initCommands,
                               preRunCommands=preRunCommands,
                               stopCommands=stopCommands,
-                              exitCommands=exitCommands)
+                              exitCommands=exitCommands,
+                              terminateCommands=terminateCommands)
 
         # Get output from the console. This should contain both the
         # "initCommands" and the "preRunCommands".
@@ -354,8 +359,10 @@
         self.continue_to_exit()
         # Get output from the console. This should contain both the
         # "exitCommands" that were run after the second breakpoint was hit
-        output = self.get_console(timeout=1.0)
+        # and the "terminateCommands" due to the debugging session ending
+        output = self.collect_console(duration=1.0)
         self.verify_commands('exitCommands', output, exitCommands)
+        self.verify_commands('terminateCommands', output, terminateCommands)
 
     @skipIfWindows
     @skipIfRemote
@@ -420,3 +427,23 @@
         # "exitCommands" that were run after the second breakpoint was hit
         output = self.get_console(timeout=1.0)
         self.verify_commands('exitCommands', output, exitCommands)
+
+    @skipIfWindows
+    @skipIfNetBSD # Hangs on NetBSD as well
+    def test_terminate_commands(self):
+        '''
+            Tests that the "terminateCommands", that can be passed during
+            launch, are run when the debugger is disconnected.
+        '''
+        self.build_and_create_debug_adaptor()
+        program = self.getBuildArtifact("a.out")
+        
+        terminateCommands = ['expr 4+2']
+        self.launch(program=program,
+                    terminateCommands=terminateCommands)
+        self.get_console()
+        # Once it's disconnected the console should contain the
+        # "terminateCommands"
+        self.vscode.request_disconnect(terminateDebuggee=True)
+        output = self.collect_console(duration=1.0)
+        self.verify_commands('terminateCommands', output, terminateCommands)
Index: lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py
===================================================================
--- lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py
+++ lldb/test/API/tools/lldb-vscode/attach/TestVSCode_attach.py
@@ -43,7 +43,6 @@
         if continueToExit:
             self.continue_to_exit()
 
-
     @skipIfWindows
     @skipIfNetBSD # Hangs on NetBSD as well
     @skipIfRemote
@@ -121,8 +120,8 @@
     def test_commands(self):
         '''
             Tests the "initCommands", "preRunCommands", "stopCommands",
-            "exitCommands", and "attachCommands" that can be passed during
-            attach.
+            "exitCommands", "terminateCommands" and "attachCommands"
+            that can be passed during attach.
 
             "initCommands" are a list of LLDB commands that get executed
             before the targt is created.
@@ -136,6 +135,8 @@
             must have a valid process in the selected target in LLDB after
             they are done executing. This allows custom commands to create any
             kind of debug session.
+            "terminateCommands" are a list of LLDB commands that get executed when
+            the debugger session terminates.
         '''
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
@@ -150,13 +151,14 @@
         preRunCommands = ['image list a.out', 'image dump sections a.out']
         stopCommands = ['frame variable', 'bt']
         exitCommands = ['expr 2+3', 'expr 3+4']
+        terminateCommands = ['expr 4+2']
         self.attach(program=program,
                     attachCommands=attachCommands,
                     initCommands=initCommands,
                     preRunCommands=preRunCommands,
                     stopCommands=stopCommands,
-                    exitCommands=exitCommands)
-
+                    exitCommands=exitCommands,
+                    terminateCommands=terminateCommands)
         # Get output from the console. This should contain both the
         # "initCommands" and the "preRunCommands".
         output = self.get_console()
@@ -187,5 +189,35 @@
         self.continue_to_exit()
         # Get output from the console. This should contain both the
         # "exitCommands" that were run after the second breakpoint was hit
-        output = self.get_console(timeout=1.0)
+        # and the "terminateCommands" due to the debugging session ending
+        output = self.collect_console(duration=1.0)
         self.verify_commands('exitCommands', output, exitCommands)
+        self.verify_commands('terminateCommands', output, terminateCommands)
+
+    @skipIfWindows
+    @skipIfNetBSD # Hangs on NetBSD as well
+    def test_terminate_commands(self):
+        '''
+            Tests that the "terminateCommands", that can be passed during
+            attach, are run when the debugger is disconnected.
+        '''
+        self.build_and_create_debug_adaptor()
+        program = self.getBuildArtifact("a.out")
+        # Here we just create a target and launch the process as a way to test
+        # if we are able to use attach commands to create any kind of a target
+        # and use it for debugging
+        attachCommands = [
+            'target create -d "%s"' % (program),
+            'process launch'
+        ]
+        terminateCommands = ['expr 4+2']
+        self.attach(program=program,
+                    attachCommands=attachCommands,
+                    terminateCommands=terminateCommands,
+                    disconnectAutomatically=False)
+        self.get_console()
+        # Once it's disconnected the console should contain the
+        # "terminateCommands"
+        self.vscode.request_disconnect(terminateDebuggee=True)
+        output = self.collect_console(duration=1.0)
+        self.verify_commands('terminateCommands', output, terminateCommands)
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
@@ -10,6 +10,7 @@
 import subprocess
 import sys
 import threading
+import time
 
 
 def dump_memory(base_addr, data, num_per_line, outfile):
@@ -148,6 +149,15 @@
         self.output_condition.release()
         return output
 
+    def collect_output(self, category, duration, clear=True):
+        end_time = time.time() + duration
+        collected_output = ""
+        while end_time > time.time():
+            output = self.get_output(category, timeout=0.25, clear=clear)
+            if output:
+                collected_output += output
+        return collected_output if collected_output else None
+
     def enqueue_recv_packet(self, packet):
         self.recv_condition.acquire()
         self.recv_packets.append(packet)
@@ -450,7 +460,8 @@
     def request_attach(self, program=None, pid=None, waitFor=None, trace=None,
                        initCommands=None, preRunCommands=None,
                        stopCommands=None, exitCommands=None,
-                       attachCommands=None, coreFile=None):
+                       attachCommands=None, terminateCommands=None,
+                       coreFile=None):
         args_dict = {}
         if pid is not None:
             args_dict['pid'] = pid
@@ -469,6 +480,8 @@
             args_dict['stopCommands'] = stopCommands
         if exitCommands:
             args_dict['exitCommands'] = exitCommands
+        if terminateCommands:
+            args_dict['terminateCommands'] = terminateCommands
         if attachCommands:
             args_dict['attachCommands'] = attachCommands
         if coreFile:
@@ -571,7 +584,8 @@
                        stopOnEntry=False, disableASLR=True,
                        disableSTDIO=False, shellExpandArguments=False,
                        trace=False, initCommands=None, preRunCommands=None,
-                       stopCommands=None, exitCommands=None, sourcePath=None,
+                       stopCommands=None, exitCommands=None,
+                       terminateCommands=None ,sourcePath=None,
                        debuggerRoot=None, launchCommands=None, sourceMap=None):
         args_dict = {
             'program': program
@@ -601,6 +615,8 @@
             args_dict['stopCommands'] = stopCommands
         if exitCommands:
             args_dict['exitCommands'] = exitCommands
+        if terminateCommands:
+            args_dict['terminateCommands'] = terminateCommands
         if sourcePath:
             args_dict['sourcePath'] = sourcePath
         if debuggerRoot:
@@ -905,7 +921,8 @@
                                       initCommands=options.initCmds,
                                       preRunCommands=options.preRunCmds,
                                       stopCommands=options.stopCmds,
-                                      exitCommands=options.exitCmds)
+                                      exitCommands=options.exitCmds,
+                                      terminateCommands=options.terminateCmds)
     else:
         response = dbg.request_launch(options.program,
                                       args=args,
@@ -916,7 +933,8 @@
                                       initCommands=options.initCmds,
                                       preRunCommands=options.preRunCmds,
                                       stopCommands=options.stopCmds,
-                                      exitCommands=options.exitCmds)
+                                      exitCommands=options.exitCmds,
+                                      terminateCommands=options.terminateCmds)
 
     if response['success']:
         if options.sourceBreakpoints:
@@ -1090,6 +1108,15 @@
               'exits. Can be specified more than once.'))
 
     parser.add_option(
+        '--terminateCommand',
+        type='string',
+        action='append',
+        dest='terminateCmds',
+        default=[],
+        help=('Specify a LLDB command that will be executed when the debugging '
+              'session is terminated. Can be specified more than once.'))
+
+    parser.add_option(
         '--env',
         type='string',
         action='append',
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
@@ -179,6 +179,9 @@
     def get_console(self, timeout=0.0):
         return self.vscode.get_output('console', timeout=timeout)
 
+    def collect_console(self, duration):
+        return self.vscode.collect_output('console', duration=duration)
+
     def get_local_as_int(self, name, threadId=None):
         value = self.vscode.get_local_variable_value(name, threadId=threadId)
         if value.startswith('0x'):
@@ -239,7 +242,8 @@
 
     def attach(self, program=None, pid=None, waitFor=None, trace=None,
                initCommands=None, preRunCommands=None, stopCommands=None,
-               exitCommands=None, attachCommands=None, coreFile=None, disconnectAutomatically=True):
+               exitCommands=None, attachCommands=None, coreFile=None,
+               disconnectAutomatically=True, terminateCommands=None):
         '''Build the default Makefile target, create the VSCode debug adaptor,
            and attach to the process.
         '''
@@ -258,7 +262,8 @@
             program=program, pid=pid, waitFor=waitFor, trace=trace,
             initCommands=initCommands, preRunCommands=preRunCommands,
             stopCommands=stopCommands, exitCommands=exitCommands,
-            attachCommands=attachCommands, coreFile=coreFile)
+            attachCommands=attachCommands, terminateCommands=terminateCommands,
+            coreFile=coreFile)
         if not (response and response['success']):
             self.assertTrue(response['success'],
                             'attach failed (%s)' % (response['message']))
@@ -267,15 +272,17 @@
                stopOnEntry=False, disableASLR=True,
                disableSTDIO=False, shellExpandArguments=False,
                trace=False, initCommands=None, preRunCommands=None,
-               stopCommands=None, exitCommands=None,sourcePath=None,
-               debuggerRoot=None, launchCommands=None, sourceMap=None):
+               stopCommands=None, exitCommands=None, terminateCommands=None,
+               sourcePath=None, debuggerRoot=None, launchCommands=None,
+               sourceMap=None, disconnectAutomatically=True):
         '''Sending launch request to vscode
         '''
 
         # Make sure we disconnect and terminate the VSCode debug adapter,
         # if we throw an exception during the test case
         def cleanup():
-            self.vscode.request_disconnect(terminateDebuggee=True)
+            if disconnectAutomatically:
+                self.vscode.request_disconnect(terminateDebuggee=True)
             self.vscode.terminate()
 
         # Execute the cleanup function during test case tear down.
@@ -297,6 +304,7 @@
             preRunCommands=preRunCommands,
             stopCommands=stopCommands,
             exitCommands=exitCommands,
+            terminateCommands=terminateCommands,
             sourcePath=sourcePath,
             debuggerRoot=debuggerRoot,
             launchCommands=launchCommands,
@@ -310,7 +318,8 @@
                          disableSTDIO=False, shellExpandArguments=False,
                          trace=False, initCommands=None, preRunCommands=None,
                          stopCommands=None, exitCommands=None,
-                         sourcePath=None, debuggerRoot=None):
+                         terminateCommands=None, sourcePath=None,
+                         debuggerRoot=None):
         '''Build the default Makefile target, create the VSCode debug adaptor,
            and launch the process.
         '''
@@ -320,4 +329,4 @@
         self.launch(program, args, cwd, env, stopOnEntry, disableASLR,
                     disableSTDIO, shellExpandArguments, trace,
                     initCommands, preRunCommands, stopCommands, exitCommands,
-                    sourcePath, debuggerRoot)
+                    terminateCommands, sourcePath, debuggerRoot)
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to