mirror of
https://github.com/intel/llvm.git
synced 2026-01-14 03:50:17 +08:00
[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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -146,3 +146,15 @@ class TestCase(TestBase):
|
||||
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")
|
||||
|
||||
Reference in New Issue
Block a user