serhiy.redko updated this revision to Diff 378575.
serhiy.redko added a comment.

- added printing of unused target related fields from launch.json in case 
launchCommands/attachCommands fields are provided.
- updated help info in for launch/attach fields according to review request.


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

https://reviews.llvm.org/D94997

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
  lldb/test/API/tools/lldb-vscode/launch/TestVSCode_launch.py
  lldb/tools/lldb-vscode/lldb-vscode.cpp
  lldb/tools/lldb-vscode/package.json

Index: lldb/tools/lldb-vscode/package.json
===================================================================
--- lldb/tools/lldb-vscode/package.json
+++ lldb/tools/lldb-vscode/package.json
@@ -215,7 +215,7 @@
 							},
 							"launchCommands": {
 								"type": "array",
-								"description": "Custom commands that are executed instead of launching a process. A target will be created with the launch arguments prior to executing these commands. The commands may optionally create a new target and must perform a launch. A valid process must exist after these commands complete or the \"launch\" will fail.",
+								"description": "Custom commands that are executed instead of launching a process. The commands must create a target and must perform a launch. A valid process must exist after these commands complete or the \"launch\" will fail. The following settings will be ignored if provided: \"program\", \"cwd\", \"args\", \"env\", \"disableASLR\", \"disableSTDIO\", \"shellExpandArguments\", \"detachOnError\", \"runInTerminal\", \"targetTriple\", \"platformName\"",
 								"default": []
 							},
 							"stopCommands": {
@@ -276,7 +276,7 @@
 							},
 							"attachCommands": {
 								"type": "array",
-								"description": "Custom commands that are executed instead of attaching to a process ID or to a process by name. These commands may optionally create a new target and must perform an attach. A valid process must exist after these commands complete or the \"attach\" will fail.",
+								"description": "Custom commands that are executed instead of attaching to a process ID or to a process by name. These commands must create a target and must perform an attach. A valid process must exist after these commands complete or the \"attach\" will fail. The following settings will be ignored if provided: \"program\", \"pid\", \"waitFor\", \"coreFile\", \"targetTriple\", \"platformName\"",
 								"default": []
 							},
 							"initCommands": {
Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===================================================================
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -616,28 +616,53 @@
   // Run any initialize LLDB commands the user specified in the launch.json
   g_vsc.RunInitCommands();

-  lldb::SBError status;
-  g_vsc.SetTarget(g_vsc.CreateTargetFromArguments(*arguments, status));
-  if (status.Fail()) {
-    response["success"] = llvm::json::Value(false);
-    EmplaceSafeString(response, "message", status.GetCString());
-    g_vsc.SendJSON(llvm::json::Value(std::move(response)));
-    return;
-  }
+  if (!attachCommands.empty()) {
+    // We have "attachCommands" that are a set of commands that are expected
+    // to execute the commands after which a process should be created. If there
+    // is no valid process after running these commands, we have failed.

-  // Run any pre run LLDB commands the user specified in the launch.json
-  g_vsc.RunPreRunCommands();
+    for (llvm::StringRef arg : {"program", "pid", "waitFor", "coreFile",
+                                "targetTriple", "platformName"}) {
+      if (arguments->get(arg) != nullptr) {
+        fprintf(stderr, "Provided argument '%s' is ignored as "
+               "incompatible with 'attachCommands'.\n", arg.str().c_str());
+      }
+    }

-  if (pid == LLDB_INVALID_PROCESS_ID && wait_for) {
-    char attach_msg[256];
-    auto attach_msg_len = snprintf(attach_msg, sizeof(attach_msg),
-                                   "Waiting to attach to \"%s\"...",
-                                   g_vsc.target.GetExecutable().GetFilename());
-    g_vsc.SendOutput(OutputType::Console,
-                     llvm::StringRef(attach_msg, attach_msg_len));
+    // Run any pre run LLDB commands the user specified in the launch.json
+    g_vsc.RunPreRunCommands();
+    g_vsc.RunLLDBCommands("Running attachCommands:", attachCommands);
+    // The custom commands are expected to create a new target
+    if (g_vsc.debugger.GetNumTargets() > 0) {
+      g_vsc.SetTarget(g_vsc.debugger.GetSelectedTarget());
+    }
+    else {
+      error.SetErrorString("attachCommands failed to create target");
+    }
   }
-  if (attachCommands.empty()) {
+  else {
     // No "attachCommands", just attach normally.
+    lldb::SBError status;
+    g_vsc.SetTarget(g_vsc.CreateTargetFromArguments(*arguments, status));
+    if (status.Fail()) {
+      response["success"] = llvm::json::Value(false);
+      EmplaceSafeString(response, "message", status.GetCString());
+      g_vsc.SendJSON(llvm::json::Value(std::move(response)));
+      return;
+    }
+
+    // Run any pre run LLDB commands the user specified in the launch.json
+    g_vsc.RunPreRunCommands();
+
+    if (pid == LLDB_INVALID_PROCESS_ID && wait_for) {
+      char attach_msg[256];
+      auto attach_msg_len = snprintf(attach_msg, sizeof(attach_msg),
+                                    "Waiting to attach to \"%s\"...",
+                                    g_vsc.target.GetExecutable().GetFilename());
+      g_vsc.SendOutput(OutputType::Console,
+                      llvm::StringRef(attach_msg, attach_msg_len));
+    }
+
     // Disable async events so the attach will be successful when we return from
     // the launch call and the launch will happen synchronously
     g_vsc.debugger.SetAsync(false);
@@ -647,14 +672,6 @@
       g_vsc.target.LoadCore(core_file.data(), error);
     // Reenable async events
     g_vsc.debugger.SetAsync(true);
-  } else {
-    // We have "attachCommands" that are a set of commands that are expected
-    // to execute the commands after which a process should be created. If there
-    // is no valid process after running these commands, we have failed.
-    g_vsc.RunLLDBCommands("Running attachCommands:", attachCommands);
-    // The custom commands might have created a new target so we should use the
-    // selected target after these commands are run.
-    g_vsc.target = g_vsc.debugger.GetSelectedTarget();
   }

   SetSourceMapFromArguments(*arguments);
@@ -1667,65 +1684,87 @@

   SetSourceMapFromArguments(*arguments);

-  lldb::SBError status;
-  g_vsc.SetTarget(g_vsc.CreateTargetFromArguments(*arguments, status));
-  if (status.Fail()) {
-    response["success"] = llvm::json::Value(false);
-    EmplaceSafeString(response, "message", status.GetCString());
-    g_vsc.SendJSON(llvm::json::Value(std::move(response)));
-    return;
-  }
+  if (!launchCommands.empty()) {
+    // if "launchCommands" are provided, then they are expected to make the launch happen for launch requests
+    // and they replace the normal logic that would implement the launch.
+    // Run any pre run LLDB commands the user specified in the launch.json
+
+    for (llvm::StringRef arg : {"program", "cwd", "args", "env", "disableASLR", "disableSTDIO",
+                                "shellExpandArguments", "detachOnError", "runInTerminal", "targetTriple",
+                                "platformName"}) {
+      if (arguments->get(arg) != nullptr) {
+        fprintf(stderr, "Provided argument '%s' is ignored as "
+               "incompatible with 'launchCommands'.\n", arg.str().c_str());
+      }
+    }

-  // Instantiate a launch info instance for the target.
-  auto launch_info = g_vsc.target.GetLaunchInfo();
-
-  // Grab the current working directory if there is one and set it in the
-  // launch info.
-  const auto cwd = GetString(arguments, "cwd");
-  if (!cwd.empty())
-    launch_info.SetWorkingDirectory(cwd.data());
-
-  // Extract any extra arguments and append them to our program arguments for
-  // when we launch
-  auto args = GetStrings(arguments, "args");
-  if (!args.empty())
-    launch_info.SetArguments(MakeArgv(args).data(), true);
-
-  // Pass any environment variables along that the user specified.
-  auto envs = GetStrings(arguments, "env");
-  if (!envs.empty())
-    launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true);
-
-  auto flags = launch_info.GetLaunchFlags();
-
-  if (GetBoolean(arguments, "disableASLR", true))
-    flags |= lldb::eLaunchFlagDisableASLR;
-  if (GetBoolean(arguments, "disableSTDIO", false))
-    flags |= lldb::eLaunchFlagDisableSTDIO;
-  if (GetBoolean(arguments, "shellExpandArguments", false))
-    flags |= lldb::eLaunchFlagShellExpandArguments;
-  const bool detatchOnError = GetBoolean(arguments, "detachOnError", false);
-  launch_info.SetDetachOnError(detatchOnError);
-  launch_info.SetLaunchFlags(flags | lldb::eLaunchFlagDebug |
-                             lldb::eLaunchFlagStopAtEntry);
-
-  // Run any pre run LLDB commands the user specified in the launch.json
-  g_vsc.RunPreRunCommands();
-
-  if (GetBoolean(arguments, "runInTerminal", false)) {
-    if (llvm::Error err = request_runInTerminal(request))
-      error.SetErrorString(llvm::toString(std::move(err)).c_str());
-  } else if (launchCommands.empty()) {
-    // Disable async events so the launch will be successful when we return from
-    // the launch call and the launch will happen synchronously
-    g_vsc.debugger.SetAsync(false);
-    g_vsc.target.Launch(launch_info, error);
-    g_vsc.debugger.SetAsync(true);
-  } else {
+    g_vsc.RunPreRunCommands();
     g_vsc.RunLLDBCommands("Running launchCommands:", launchCommands);
-    // The custom commands might have created a new target so we should use the
-    // selected target after these commands are run.
-    g_vsc.target = g_vsc.debugger.GetSelectedTarget();
+    // The custom commands are expected to create a new target
+    if (g_vsc.debugger.GetNumTargets() > 0) {
+      g_vsc.SetTarget(g_vsc.debugger.GetSelectedTarget());
+    }
+    else {
+      error.SetErrorString("launchCommands failed to create target");
+    }
+  }
+  else {
+    // the normal logic that would implement the launch
+    lldb::SBError status;
+    g_vsc.SetTarget(g_vsc.CreateTargetFromArguments(*arguments, status));
+    if (status.Fail()) {
+      response["success"] = llvm::json::Value(false);
+      EmplaceSafeString(response, "message", status.GetCString());
+      g_vsc.SendJSON(llvm::json::Value(std::move(response)));
+      return;
+    }
+
+    // Instantiate a launch info instance for the target.
+    auto launch_info = g_vsc.target.GetLaunchInfo();
+
+    // Grab the current working directory if there is one and set it in the
+    // launch info.
+    const auto cwd = GetString(arguments, "cwd");
+    if (!cwd.empty())
+      launch_info.SetWorkingDirectory(cwd.data());
+
+    // Extract any extra arguments and append them to our program arguments for
+    // when we launch
+    auto args = GetStrings(arguments, "args");
+    if (!args.empty())
+      launch_info.SetArguments(MakeArgv(args).data(), true);
+
+    // Pass any environment variables along that the user specified.
+    auto envs = GetStrings(arguments, "env");
+    if (!envs.empty())
+      launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true);
+
+    auto flags = launch_info.GetLaunchFlags();
+
+    if (GetBoolean(arguments, "disableASLR", true))
+      flags |= lldb::eLaunchFlagDisableASLR;
+    if (GetBoolean(arguments, "disableSTDIO", false))
+      flags |= lldb::eLaunchFlagDisableSTDIO;
+    if (GetBoolean(arguments, "shellExpandArguments", false))
+      flags |= lldb::eLaunchFlagShellExpandArguments;
+    const bool detatchOnError = GetBoolean(arguments, "detachOnError", false);
+    launch_info.SetDetachOnError(detatchOnError);
+    launch_info.SetLaunchFlags(flags | lldb::eLaunchFlagDebug |
+                              lldb::eLaunchFlagStopAtEntry);
+
+    // Run any pre run LLDB commands the user specified in the launch.json
+    g_vsc.RunPreRunCommands();
+
+    if (GetBoolean(arguments, "runInTerminal", false)) {
+      if (llvm::Error err = request_runInTerminal(request))
+        error.SetErrorString(llvm::toString(std::move(err)).c_str());
+    } else {
+      // Disable async events so the launch will be successful when we return from
+      // the launch call and the launch will happen synchronously
+      g_vsc.debugger.SetAsync(false);
+      g_vsc.target.Launch(launch_info, error);
+      g_vsc.debugger.SetAsync(true);
+    }
   }

   if (error.Fail()) {
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
@@ -378,6 +378,7 @@
         '''
         self.build_and_create_debug_adaptor()
         program = self.getBuildArtifact("a.out")
+        execSearchPaths = '/unique/path/to/symbols/launch/test'

         source = 'main.c'
         first_line = line_number(source, '// breakpoint 1')
@@ -387,6 +388,7 @@
         # also we can verify that "stopCommands" get run as the
         # breakpoints get hit
         launchCommands = [
+            'settings set target.exec-search-paths "%s"' % (execSearchPaths),
             'target create "%s"' % (program),
             'breakpoint s -f main.c -l %d' % first_line,
             'breakpoint s -f main.c -l %d' % second_line,
@@ -396,7 +398,7 @@
         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']
+        exitCommands = ['expr 2+3', 'expr 3+4', 'settings show target.exec-search-paths']
         self.launch(program,
                     initCommands=initCommands,
                     preRunCommands=preRunCommands,
@@ -433,6 +435,8 @@
         # "exitCommands" that were run after the second breakpoint was hit
         output = self.get_console(timeout=1.0)
         self.verify_commands('exitCommands', output, exitCommands)
+        # confirm that output contains correct target.exec-search-paths value
+        self.verify_contains_text('exitCommands', output, execSearchPaths)

     @skipIfWindows
     @skipIfNetBSD # Hangs on NetBSD as well
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
@@ -125,6 +125,13 @@
                             "verify '%s' found in console output for '%s'" % (
                                 cmd, flavor))

+    def verify_contains_text(self, flavor, output, text):
+        self.assertTrue(output and len(output) > 0, "expect console output")
+        found = text in output
+        self.assertTrue(found,
+                        "verify '%s' found in console output for '%s'" % (
+                            text, flavor))
+
     def get_dict_value(self, d, key_path):
         '''Verify each key in the key_path array is in contained in each
            dictionary within "d". Assert if any key isn't in the
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to