Skip to content

[Swift] Implement error handling for dwim-print -O #8920

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lldb/include/lldb/Core/ValueObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ class ValueObject {
std::string &destination,
const TypeSummaryOptions &options);

const char *GetObjectDescription();
llvm::Expected<std::string> GetObjectDescription();

bool HasSpecialPrintableRepresentation(
ValueObjectRepresentationStyle val_obj_display,
Expand Down Expand Up @@ -657,9 +657,9 @@ class ValueObject {

virtual SymbolContextScope *GetSymbolContextScope();

void Dump(Stream &s);
llvm::Error Dump(Stream &s);

void Dump(Stream &s, const DumpValueObjectOptions &options);
llvm::Error Dump(Stream &s, const DumpValueObjectOptions &options);

static lldb::ValueObjectSP
CreateValueObjectFromExpression(llvm::StringRef name,
Expand Down
9 changes: 5 additions & 4 deletions lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ValueObjectPrinter {

~ValueObjectPrinter() = default;

bool PrintValueObject();
llvm::Error PrintValueObject();

protected:
typedef std::set<uint64_t> InstancePointersSet;
Expand Down Expand Up @@ -76,7 +76,7 @@ class ValueObjectPrinter {

void SetupMostSpecializedValue();

const char *GetDescriptionForDisplay();
llvm::Expected<std::string> GetDescriptionForDisplay();

const char *GetRootNameForDisplay();

Expand Down Expand Up @@ -109,7 +109,8 @@ class ValueObjectPrinter {

bool PrintValueAndSummaryIfNeeded(bool &value_printed, bool &summary_printed);

bool PrintObjectDescriptionIfNeeded(bool value_printed, bool summary_printed);
llvm::Error PrintObjectDescriptionIfNeeded(bool value_printed,
bool summary_printed);

bool
ShouldPrintChildren(DumpValueObjectOptions::PointerDepth &curr_ptr_depth);
Expand All @@ -133,7 +134,7 @@ class ValueObjectPrinter {
PrintChildren(bool value_printed, bool summary_printed,
const DumpValueObjectOptions::PointerDepth &curr_ptr_depth);

void PrintChildrenIfNeeded(bool value_printed, bool summary_printed);
llvm::Error PrintChildrenIfNeeded(bool value_printed, bool summary_printed);

bool PrintChildrenOneLiner(bool hide_names);

Expand Down
9 changes: 5 additions & 4 deletions lldb/include/lldb/Target/LanguageRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,12 @@ class LanguageRuntime : public Runtime, public PluginInterface {
return nullptr;
}

virtual bool GetObjectDescription(Stream &str, ValueObject &object) = 0;

virtual bool GetObjectDescription(Stream &str, Value &value,
ExecutionContextScope *exe_scope) = 0;
virtual llvm::Error GetObjectDescription(Stream &str,
ValueObject &object) = 0;

virtual llvm::Error
GetObjectDescription(Stream &str, Value &value,
ExecutionContextScope *exe_scope) = 0;

struct VTableInfo {
Address addr; /// Address of the vtable's virtual function table
Expand Down
22 changes: 22 additions & 0 deletions lldb/include/lldb/Utility/ErrorMessages.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===-- ErrorMessages.h -----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_UTILITY_ERROR_MESSAGES_H
#define LLDB_UTILITY_ERROR_MESSAGES_H

#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include <string>

namespace lldb_private {

/// Produce a human-readable rendition of an ExpressionResults value.
std::string toString(lldb::ExpressionResults e);

} // namespace lldb_private
#endif
16 changes: 11 additions & 5 deletions lldb/source/API/SBValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,10 @@ const char *SBValue::GetObjectDescription() {
if (!value_sp)
return nullptr;

return ConstString(value_sp->GetObjectDescription()).GetCString();
llvm::Expected<std::string> str = value_sp->GetObjectDescription();
if (!str)
return ConstString("error: " + toString(str.takeError())).AsCString();
return ConstString(*str).AsCString();
}

SBType SBValue::GetType() {
Expand Down Expand Up @@ -1210,11 +1213,14 @@ bool SBValue::GetDescription(SBStream &description) {

ValueLocker locker;
lldb::ValueObjectSP value_sp(GetSP(locker));
if (value_sp)
value_sp->Dump(strm);
else
if (value_sp) {
if (llvm::Error error = value_sp->Dump(strm)) {
strm << "error: " << toString(std::move(error));
return false;
}
} else {
strm.PutCString("No value");

}
return true;
}

Expand Down
8 changes: 6 additions & 2 deletions lldb/source/Breakpoint/Watchpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,9 @@ bool Watchpoint::DumpSnapshots(Stream *s, const char *prefix) const {
.SetHideRootType(true)
.SetHideRootName(true)
.SetHideName(true);
m_old_value_sp->Dump(strm, options);
if (llvm::Error error = m_old_value_sp->Dump(strm, options))
strm << "error: " << toString(std::move(error));

if (strm.GetData())
values_ss.Printf("old value: %s", strm.GetData());
}
Expand All @@ -324,7 +326,9 @@ bool Watchpoint::DumpSnapshots(Stream *s, const char *prefix) const {
.SetHideRootType(true)
.SetHideRootName(true)
.SetHideName(true);
m_new_value_sp->Dump(strm, options);
if (llvm::Error error = m_new_value_sp->Dump(strm, options))
strm << "error: " << toString(std::move(error));

if (strm.GetData())
values_ss.Printf("new value: %s", strm.GetData());
}
Expand Down
93 changes: 49 additions & 44 deletions lldb/source/Commands/CommandObjectDWIMPrint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,28 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
}
};

// Dump `valobj` according to whether `po` was requested or not.
auto dump_val_object = [&](ValueObject &valobj) {
if (is_po) {
StreamString temp_result_stream;
if (llvm::Error error = valobj.Dump(temp_result_stream, dump_options)) {
result.AppendError(toString(std::move(error)));
return;
}
llvm::StringRef output = temp_result_stream.GetString();
maybe_add_hint(output);
result.GetOutputStream() << output;
} else {
llvm::Error error =
valobj.Dump(result.GetOutputStream(), dump_options);
if (error) {
result.AppendError(toString(std::move(error)));
return;
}
}
result.SetStatus(eReturnStatusSuccessFinishResult);
};

// First, try `expr` as the name of a frame variable.
if (frame) {
auto valobj_sp = frame->FindVariable(ConstString(expr));
Expand All @@ -155,16 +177,7 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
flags, expr);
}

if (is_po) {
StreamString temp_result_stream;
valobj_sp->Dump(temp_result_stream, dump_options);
llvm::StringRef output = temp_result_stream.GetString();
maybe_add_hint(output);
result.GetOutputStream() << output;
} else {
valobj_sp->Dump(result.GetOutputStream(), dump_options);
}
result.SetStatus(eReturnStatusSuccessFinishResult);
dump_val_object(*valobj_sp);
return;
}
}
Expand Down Expand Up @@ -211,8 +224,7 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
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);
dump_val_object(*valobj_sp);
return;
}

Expand All @@ -233,43 +245,36 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
error_stream << " " << fixed_expression << "\n";
}

if (expr_result == eExpressionCompleted) {
if (verbosity != eDWIMPrintVerbosityNone) {
StringRef flags;
if (args.HasArgs())
flags = args.GetArgStringWithDelimiter();
result.AppendMessageWithFormatv("note: ran `expression {0}{1}`", flags,
expr);
}

if (valobj_sp->GetError().GetError() != UserExpression::kNoResult) {
if (is_po) {
StreamString temp_result_stream;
valobj_sp->Dump(temp_result_stream, dump_options);
llvm::StringRef output = temp_result_stream.GetString();
maybe_add_hint(output);
result.GetOutputStream() << output;
} else {
valobj_sp->Dump(result.GetOutputStream(), dump_options);
}
}

if (suppress_result)
if (auto result_var_sp =
target.GetPersistentVariable(valobj_sp->GetName())) {
auto language = valobj_sp->GetPreferredDisplayLanguage();
if (auto *persistent_state =
target.GetPersistentExpressionStateForLanguage(language))
persistent_state->RemovePersistentVariable(result_var_sp);
}

result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
// If the expression failed, return an error.
if (expr_result != eExpressionCompleted) {
if (valobj_sp)
result.SetError(valobj_sp->GetError());
else
result.AppendErrorWithFormatv(
"unknown error evaluating expression `{0}`", expr);
return;
}

if (verbosity != eDWIMPrintVerbosityNone) {
StringRef flags;
if (args.HasArgs())
flags = args.GetArgStringWithDelimiter();
result.AppendMessageWithFormatv("note: ran `expression {0}{1}`", flags,
expr);
}

if (valobj_sp->GetError().GetError() != UserExpression::kNoResult)
dump_val_object(*valobj_sp);
else
result.SetStatus(eReturnStatusSuccessFinishResult);

if (suppress_result)
if (auto result_var_sp =
target.GetPersistentVariable(valobj_sp->GetName())) {
auto language = valobj_sp->GetPreferredDisplayLanguage();
if (auto *persistent_state =
target.GetPersistentExpressionStateForLanguage(language))
persistent_state->RemovePersistentVariable(result_var_sp);
}
}
}
6 changes: 5 additions & 1 deletion lldb/source/Commands/CommandObjectExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,11 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
options.SetVariableFormatDisplayLanguage(
result_valobj_sp->GetPreferredDisplayLanguage());

result_valobj_sp->Dump(output_stream, options);
if (llvm::Error error =
result_valobj_sp->Dump(output_stream, options)) {
result.AppendError(toString(std::move(error)));
return false;
}

if (suppress_result)
if (auto result_var_sp =
Expand Down
18 changes: 13 additions & 5 deletions lldb/source/Commands/CommandObjectFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ class CommandObjectFrameDiagnose : public CommandObjectParsed {
assert(valobj_sp.get() && "Must have a valid ValueObject to print");
ValueObjectPrinter printer(*valobj_sp, &result.GetOutputStream(),
options);
printer.PrintValueObject();
if (llvm::Error error = printer.PrintValueObject())
result.AppendError(toString(std::move(error)));
}

CommandOptions m_options;
Expand Down Expand Up @@ -609,7 +610,9 @@ may even involve JITing and running code in the target program.)");
show_module))
s.PutCString(": ");
}
valobj_sp->Dump(result.GetOutputStream(), options);
auto &strm = result.GetOutputStream();
if (llvm::Error error = valobj_sp->Dump(strm, options))
result.AppendError(toString(std::move(error)));
}
}
} else {
Expand Down Expand Up @@ -651,7 +654,8 @@ may even involve JITing and running code in the target program.)");
Stream &output_stream = result.GetOutputStream();
options.SetRootValueObjectName(
valobj_sp->GetParent() ? entry.c_str() : nullptr);
valobj_sp->Dump(output_stream, options);
if (llvm::Error error = valobj_sp->Dump(output_stream, options))
result.AppendError(toString(std::move(error)));
} else {
if (auto error_cstr = error.AsCString(nullptr))
result.AppendError(error_cstr);
Expand Down Expand Up @@ -702,7 +706,9 @@ may even involve JITing and running code in the target program.)");
valobj_sp->GetPreferredDisplayLanguage());
options.SetRootValueObjectName(
var_sp ? var_sp->GetName().AsCString() : nullptr);
valobj_sp->Dump(result.GetOutputStream(), options);
if (llvm::Error error =
valobj_sp->Dump(result.GetOutputStream(), options))
result.AppendError(toString(std::move(error)));
}
}
}
Expand All @@ -723,7 +729,9 @@ may even involve JITing and running code in the target program.)");
options.SetVariableFormatDisplayLanguage(
rec_value_sp->GetPreferredDisplayLanguage());
options.SetRootValueObjectName(rec_value_sp->GetName().AsCString());
rec_value_sp->Dump(result.GetOutputStream(), options);
if (llvm::Error error =
rec_value_sp->Dump(result.GetOutputStream(), options))
result.AppendError(toString(std::move(error)));
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion lldb/source/Commands/CommandObjectMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,10 @@ class CommandObjectMemoryRead : public CommandObjectParsed {
DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
eLanguageRuntimeDescriptionDisplayVerbosityFull, format));

valobj_sp->Dump(*output_stream_p, options);
if (llvm::Error error = valobj_sp->Dump(*output_stream_p, options)) {
result.AppendError(toString(std::move(error)));
return;
}
} else {
result.AppendErrorWithFormat(
"failed to create a value object for: (%s) %s\n",
Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Commands/CommandObjectTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,8 @@ class CommandObjectTargetVariable : public CommandObjectParsed {

options.SetRootValueObjectName(root_name);

valobj_sp->Dump(s, options);
if (llvm::Error error = valobj_sp->Dump(s, options))
s << "error: " << toString(std::move(error));
}

static size_t GetVariableCallback(void *baton, const char *name,
Expand Down
14 changes: 10 additions & 4 deletions lldb/source/Commands/CommandObjectThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1367,7 +1367,10 @@ class CommandObjectThreadException : public CommandObjectIterateOverThreads {
Stream &strm = result.GetOutputStream();
ValueObjectSP exception_object_sp = thread_sp->GetCurrentException();
if (exception_object_sp) {
exception_object_sp->Dump(strm);
if (llvm::Error error = exception_object_sp->Dump(strm)) {
result.AppendError(toString(std::move(error)));
return false;
}
}

ThreadSP exception_thread_sp = thread_sp->GetCurrentExceptionBacktrace();
Expand Down Expand Up @@ -1419,9 +1422,12 @@ class CommandObjectThreadSiginfo : public CommandObjectIterateOverThreads {
return false;
}
ValueObjectSP exception_object_sp = thread_sp->GetSiginfoValue();
if (exception_object_sp)
exception_object_sp->Dump(strm);
else
if (exception_object_sp) {
if (llvm::Error error = exception_object_sp->Dump(strm)) {
result.AppendError(toString(std::move(error)));
return false;
}
} else
strm.Printf("(no siginfo)\n");
strm.PutChar('\n');

Expand Down
Loading