[Lldb-commits] [lldb] 4da2b54 - [lldb] Fix dwim-print to not delete non-result persistent variables (#85152)

via lldb-commits lldb-commits at lists.llvm.org
Fri Mar 15 16:09:29 PDT 2024


Author: Dave Lee
Date: 2024-03-15T16:09:24-07:00
New Revision: 4da2b542b142dac441722e044ee75da2475d9a20

URL: https://github.com/llvm/llvm-project/commit/4da2b542b142dac441722e044ee75da2475d9a20
DIFF: https://github.com/llvm/llvm-project/commit/4da2b542b142dac441722e044ee75da2475d9a20.diff

LOG: [lldb] Fix dwim-print to not delete non-result persistent variables (#85152)

`EvaluateExpression` does not always create a new persistent result. If the expression 
is a bare persistent variable, then a new persistent result is not created. This means 
the caller can't assume a new persistent result is created for each evaluation. 
However, `dwim-print` was doing exactly that: assuming a new persistent result for each 
evaluation. This resulted in a bug:

```
(lldb) p int $j = 23
(lldb) p $j
(lldb) p $j
```

The first `p $j` would not create a persistent result, and so `dwim-print` would 
inadvertently delete `$j`. The second `p $j` would fail.

The fix is to try `expr` as a persistent variable, after trying `expr` as a frame 
variable. For persistent variables, this avoids calling `EvaluateExpression`.

Resolves https://github.com/llvm/llvm-project/issues/84806

rdar://124688427

Added: 
    

Modified: 
    lldb/source/Commands/CommandObjectDWIMPrint.cpp
    lldb/test/API/commands/dwim-print/TestDWIMPrint.py

Removed: 
    


################################################################################
diff  --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index b183cb423111fb..a88da986bb384f 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -23,7 +23,6 @@
 #include "lldb/lldb-enumerations.h"
 #include "lldb/lldb-forward.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/Support/FormatVariadic.h"
 
 #include <regex>
 
@@ -161,7 +160,17 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
     }
   }
 
-  // Second, also lastly, try `expr` as a source expression to evaluate.
+  // Second, try `expr` as a persistent variable.
+  if (expr.starts_with("$"))
+    if (auto *state = target.GetPersistentExpressionStateForLanguage(language))
+      if (auto var_sp = state->GetVariable(expr))
+        if (auto valobj_sp = var_sp->GetValueObject()) {
+          valobj_sp->Dump(result.GetOutputStream(), dump_options);
+          result.SetStatus(eReturnStatusSuccessFinishResult);
+          return;
+        }
+
+  // Third, and lastly, try `expr` as a source expression to evaluate.
   {
     auto *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
     ValueObjectSP valobj_sp;

diff  --git a/lldb/test/API/commands/dwim-print/TestDWIMPrint.py b/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
index 040632096c70e7..c650b1e3533e08 100644
--- a/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
+++ b/lldb/test/API/commands/dwim-print/TestDWIMPrint.py
@@ -146,3 +146,15 @@ def test_void_result(self):
             self, "// break here", lldb.SBFileSpec("main.c")
         )
         self.expect("dwim-print (void)15", matching=False, patterns=["(?i)error"])
+
+    def test_preserves_persistent_variables(self):
+        """Test dwim-print does not delete persistent variables."""
+        self.build()
+        lldbutil.run_to_source_breakpoint(
+            self, "// break here", lldb.SBFileSpec("main.c")
+        )
+        self.expect("dwim-print int $i = 15")
+        # Run the same expression twice and verify success. This ensures the
+        # first command does not delete the persistent variable.
+        for _ in range(2):
+            self.expect("dwim-print $i", startstr="(int) 15")


        


More information about the lldb-commits mailing list