Skip to content

Commit 4da2b54

Browse files
authored
[lldb] Fix dwim-print to not delete non-result persistent variables (llvm#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 llvm#84806 rdar://124688427
1 parent 8f2632c commit 4da2b54

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

lldb/source/Commands/CommandObjectDWIMPrint.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include "lldb/lldb-enumerations.h"
2424
#include "lldb/lldb-forward.h"
2525
#include "llvm/ADT/StringRef.h"
26-
#include "llvm/Support/FormatVariadic.h"
2726

2827
#include <regex>
2928

@@ -161,7 +160,17 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
161160
}
162161
}
163162

164-
// Second, also lastly, try `expr` as a source expression to evaluate.
163+
// Second, try `expr` as a persistent variable.
164+
if (expr.starts_with("$"))
165+
if (auto *state = target.GetPersistentExpressionStateForLanguage(language))
166+
if (auto var_sp = state->GetVariable(expr))
167+
if (auto valobj_sp = var_sp->GetValueObject()) {
168+
valobj_sp->Dump(result.GetOutputStream(), dump_options);
169+
result.SetStatus(eReturnStatusSuccessFinishResult);
170+
return;
171+
}
172+
173+
// Third, and lastly, try `expr` as a source expression to evaluate.
165174
{
166175
auto *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
167176
ValueObjectSP valobj_sp;

lldb/test/API/commands/dwim-print/TestDWIMPrint.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,15 @@ def test_void_result(self):
146146
self, "// break here", lldb.SBFileSpec("main.c")
147147
)
148148
self.expect("dwim-print (void)15", matching=False, patterns=["(?i)error"])
149+
150+
def test_preserves_persistent_variables(self):
151+
"""Test dwim-print does not delete persistent variables."""
152+
self.build()
153+
lldbutil.run_to_source_breakpoint(
154+
self, "// break here", lldb.SBFileSpec("main.c")
155+
)
156+
self.expect("dwim-print int $i = 15")
157+
# Run the same expression twice and verify success. This ensures the
158+
# first command does not delete the persistent variable.
159+
for _ in range(2):
160+
self.expect("dwim-print $i", startstr="(int) 15")

0 commit comments

Comments
 (0)