[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