[Lldb-commits] [lldb] [LLDB] Add a target.launch-working-dir setting (PR #113521)

via lldb-commits lldb-commits at lists.llvm.org
Wed Oct 23 21:23:17 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Walter Erquinigo (walter-erquinigo)

<details>
<summary>Changes</summary>

Internally we use bazel in a way in which it can drop you in a LLDB session with the target launched in a particular cwd, which is needed for things to work. We've been making this automation work via `process launch -w`. However, if later the user wants to restart the process with `r`, then they end up using a different cwd for relaunching the process. As a way to fix this, I'm adding a target-level setting that allows overriding the cwd used for launching the process without needing the user to specify it manually.

---
Full diff: https://github.com/llvm/llvm-project/pull/113521.diff


5 Files Affected:

- (modified) lldb/include/lldb/Target/Target.h (+3) 
- (modified) lldb/source/Commands/CommandObjectProcess.cpp (+5) 
- (modified) lldb/source/Target/Target.cpp (+9) 
- (modified) lldb/source/Target/TargetProperties.td (+4) 
- (modified) lldb/test/API/commands/process/launch/TestProcessLaunch.py (+45) 


``````````diff
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index e4848f19e64d62..0e8bbb41f29941 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -37,6 +37,7 @@
 #include "lldb/Utility/RealpathPrefixes.h"
 #include "lldb/Utility/Timeout.h"
 #include "lldb/lldb-public.h"
+#include "llvm/ADT/StringRef.h"
 
 namespace lldb_private {
 
@@ -114,6 +115,8 @@ class TargetProperties : public Properties {
 
   void SetDisableSTDIO(bool b);
 
+  std::optional<llvm::StringRef> GetLaunchWorkingDirectory() const;
+
   const char *GetDisassemblyFlavor() const;
 
   InlineStrategy GetInlineStrategy() const;
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index e7c7d07ad47722..297c94c1f0a055 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -201,6 +201,11 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach {
     if (target->GetDisableSTDIO())
       m_options.launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO);
 
+    if (std::optional<llvm::StringRef> wd =
+            target->GetLaunchWorkingDirectory()) {
+      m_options.launch_info.SetWorkingDirectory(FileSpec(*wd));
+    }
+
     // Merge the launch info environment with the target environment.
     Environment target_env = target->GetEnvironment();
     m_options.launch_info.GetEnvironment().insert(target_env.begin(),
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 04395e37f0425d..ef4dabf00c1a9e 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -4428,6 +4428,15 @@ void TargetProperties::SetDisableSTDIO(bool b) {
   const uint32_t idx = ePropertyDisableSTDIO;
   SetPropertyAtIndex(idx, b);
 }
+std::optional<llvm::StringRef>
+TargetProperties::GetLaunchWorkingDirectory() const {
+  const uint32_t idx = ePropertyLaunchWorkingDir;
+  llvm::StringRef value = GetPropertyAtIndexAs<llvm::StringRef>(
+      idx, g_target_properties[idx].default_cstr_value);
+  if (value.empty())
+    return {};
+  return value;
+}
 
 const char *TargetProperties::GetDisassemblyFlavor() const {
   const uint32_t idx = ePropertyDisassemblyFlavor;
diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td
index fb61478fb752dc..613442501d6b6d 100644
--- a/lldb/source/Target/TargetProperties.td
+++ b/lldb/source/Target/TargetProperties.td
@@ -201,6 +201,10 @@ let Definition = "target" in {
   def DebugUtilityExpression: Property<"debug-utility-expression", "Boolean">,
     DefaultFalse,
     Desc<"Enable debugging of LLDB-internal utility expressions.">;
+  def LaunchWorkingDir: Property<"launch-working-dir", "String">,
+    DefaultStringValue<"">,
+    Desc<"An override for the working directory to use when launching processes. "
+         "It's not used when empty.">;
 }
 
 let Definition = "process_experimental" in {
diff --git a/lldb/test/API/commands/process/launch/TestProcessLaunch.py b/lldb/test/API/commands/process/launch/TestProcessLaunch.py
index 45f9f494ab8f5c..f3afc385a56086 100644
--- a/lldb/test/API/commands/process/launch/TestProcessLaunch.py
+++ b/lldb/test/API/commands/process/launch/TestProcessLaunch.py
@@ -8,6 +8,7 @@
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
+from pathlib import Path
 
 
 class ProcessLaunchTestCase(TestBase):
@@ -206,3 +207,47 @@ def test_environment_with_special_char(self):
         self.assertEqual(value, evil_var)
         process.Continue()
         self.assertState(process.GetState(), lldb.eStateExited, PROCESS_EXITED)
+
+    def test_target_launch_working_dir_prop(self):
+        """Test that the setting `target.launch-working-dir` is correctly used when launching a process."""
+        d = {"CXX_SOURCES": "print_cwd.cpp"}
+        self.build(dictionary=d)
+        self.setTearDownCleanup(d)
+        exe = self.getBuildArtifact("a.out")
+        self.runCmd("file " + exe)
+
+        mywd = "my_working_dir"
+        out_file_name = "my_working_dir_test.out"
+
+        my_working_dir_path = self.getBuildArtifact(mywd)
+        lldbutil.mkdir_p(my_working_dir_path)
+        out_file_path = os.path.join(my_working_dir_path, out_file_name)
+        another_working_dir_path = Path(
+            os.path.join(my_working_dir_path, "..")
+        ).resolve()
+
+        # Check that we correctly set the working dir
+        self.runCmd(
+            f"settings set target.launch-working-dir {another_working_dir_path}"
+        )
+        launch_command = f"process launch -o {out_file_path}"
+
+        self.expect(
+            launch_command,
+            patterns=["Process .* launched: .*a.out"],
+        )
+
+        out = lldbutil.read_file_on_target(self, out_file_path)
+        self.assertIn(f"stdout: {another_working_dir_path}", out)
+
+        # Check that we can unset the setting
+        self.runCmd(f"settings set target.launch-working-dir ''")
+        launch_command = f"process launch -o {out_file_path}"
+
+        self.expect(
+            launch_command,
+            patterns=["Process .* launched: .*a.out"],
+        )
+
+        out = lldbutil.read_file_on_target(self, out_file_path)
+        self.assertNotIn(f"stdout: {another_working_dir_path}", out)

``````````

</details>


https://github.com/llvm/llvm-project/pull/113521


More information about the lldb-commits mailing list