Skip to content

Commit f23c10f

Browse files
authored
[lldb] Fallback to expression eval when Dump of variable fails in dwim-print (#151374)
Previously, when dwim-print finds a frame variables, it returns immediately after calling `Dump`, even if `Dump` returns an error. This is most likely to happen when evaluating an object description, ie `po`. This changes dwim-print to continue on to expression evaluation when `Dump`ing a variable returns an error . This is to allow for diagnostics that match `expression`.
1 parent 5d489b8 commit f23c10f

File tree

1 file changed

+29
-18
lines changed

1 file changed

+29
-18
lines changed

lldb/source/Commands/CommandObjectDWIMPrint.cpp

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
1919
#include "lldb/Target/StackFrame.h"
2020
#include "lldb/Utility/ConstString.h"
21+
#include "lldb/Utility/LLDBLog.h"
22+
#include "lldb/Utility/Log.h"
2123
#include "lldb/ValueObject/ValueObject.h"
2224
#include "lldb/lldb-defines.h"
2325
#include "lldb/lldb-enumerations.h"
2426
#include "lldb/lldb-forward.h"
2527
#include "llvm/ADT/StringRef.h"
28+
#include "llvm/Support/Error.h"
2629

2730
#include <regex>
2831

@@ -132,27 +135,22 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
132135
};
133136

134137
// Dump `valobj` according to whether `po` was requested or not.
135-
auto dump_val_object = [&](ValueObject &valobj) {
138+
auto dump_val_object = [&](ValueObject &valobj) -> Error {
136139
if (is_po) {
137140
StreamString temp_result_stream;
138-
if (llvm::Error error = valobj.Dump(temp_result_stream, dump_options)) {
139-
result.AppendError(toString(std::move(error)));
140-
return;
141-
}
141+
if (Error err = valobj.Dump(temp_result_stream, dump_options))
142+
return err;
142143
llvm::StringRef output = temp_result_stream.GetString();
143144
maybe_add_hint(output);
144145
result.GetOutputStream() << output;
145146
} else {
146-
llvm::Error error =
147-
valobj.Dump(result.GetOutputStream(), dump_options);
148-
if (error) {
149-
result.AppendError(toString(std::move(error)));
150-
return;
151-
}
147+
if (Error err = valobj.Dump(result.GetOutputStream(), dump_options))
148+
return err;
152149
}
153150
m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
154151
m_cmd_name);
155152
result.SetStatus(eReturnStatusSuccessFinishResult);
153+
return Error::success();
156154
};
157155

158156
// First, try `expr` as a _limited_ frame variable expression path: only the
@@ -186,8 +184,13 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
186184
expr);
187185
}
188186

189-
dump_val_object(*valobj_sp);
190-
return;
187+
Error err = dump_val_object(*valobj_sp);
188+
if (!err)
189+
return;
190+
191+
// Dump failed, continue on to expression evaluation.
192+
LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), std::move(err),
193+
"could not print frame variable '{1}': {0}", expr);
191194
}
192195
}
193196

@@ -196,8 +199,14 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
196199
if (auto *state = target.GetPersistentExpressionStateForLanguage(language))
197200
if (auto var_sp = state->GetVariable(expr))
198201
if (auto valobj_sp = var_sp->GetValueObject()) {
199-
dump_val_object(*valobj_sp);
200-
return;
202+
Error err = dump_val_object(*valobj_sp);
203+
if (!err)
204+
return;
205+
206+
// Dump failed, continue on to expression evaluation.
207+
LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), std::move(err),
208+
"could not print persistent variable '{1}': {0}",
209+
expr);
201210
}
202211

203212
// Third, and lastly, try `expr` as a source expression to evaluate.
@@ -248,10 +257,12 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
248257
result.AppendNoteWithFormatv("ran `expression {0}{1}`", flags, expr);
249258
}
250259

251-
if (valobj_sp->GetError().GetError() != UserExpression::kNoResult)
252-
dump_val_object(*valobj_sp);
253-
else
260+
if (valobj_sp->GetError().GetError() != UserExpression::kNoResult) {
261+
if (Error err = dump_val_object(*valobj_sp))
262+
result.SetError(std::move(err));
263+
} else {
254264
result.SetStatus(eReturnStatusSuccessFinishNoResult);
265+
}
255266

256267
if (suppress_result)
257268
if (auto result_var_sp =

0 commit comments

Comments
 (0)