Skip to content

Commit 38b55e1

Browse files
committed
[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 (cherry picked from commit 4da2b54)
1 parent 6dadfbc commit 38b55e1

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
@@ -25,7 +25,6 @@
2525
#include "lldb/lldb-forward.h"
2626
#include "lldb/lldb-types.h"
2727
#include "llvm/ADT/StringRef.h"
28-
#include "llvm/Support/FormatVariadic.h"
2928

3029
#include <regex>
3130

@@ -210,7 +209,17 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
210209
}
211210
// END SWIFT
212211

213-
// Second, also lastly, try `expr` as a source expression to evaluate.
212+
// Second, try `expr` as a persistent variable.
213+
if (expr.starts_with("$"))
214+
if (auto *state = target.GetPersistentExpressionStateForLanguage(language))
215+
if (auto var_sp = state->GetVariable(expr))
216+
if (auto valobj_sp = var_sp->GetValueObject()) {
217+
valobj_sp->Dump(result.GetOutputStream(), dump_options);
218+
result.SetStatus(eReturnStatusSuccessFinishResult);
219+
return;
220+
}
221+
222+
// Third, and lastly, try `expr` as a source expression to evaluate.
214223
{
215224
auto *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
216225
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)