Skip to content

[Cherry-pick into swift/release/6.1] [lldb] Expose structured errors in SBError (#120784) #9784

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
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
89 changes: 60 additions & 29 deletions lldb/bindings/python/static-binding/LLDBWrapPython.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30287,6 +30287,34 @@ SWIGINTERN PyObject *_wrap_SBError_GetError(PyObject *self, PyObject *args) {
}


SWIGINTERN PyObject *_wrap_SBError_GetErrorData(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
lldb::SBError *arg1 = (lldb::SBError *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
lldb::SBStructuredData result;

(void)self;
if (!args) SWIG_fail;
swig_obj[0] = args;
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBError, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBError_GetErrorData" "', argument " "1"" of type '" "lldb::SBError const *""'");
}
arg1 = reinterpret_cast< lldb::SBError * >(argp1);
{
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
result = ((lldb::SBError const *)arg1)->GetErrorData();
SWIG_PYTHON_THREAD_END_ALLOW;
}
resultobj = SWIG_NewPointerObj((new lldb::SBStructuredData(result)), SWIGTYPE_p_lldb__SBStructuredData, SWIG_POINTER_OWN | 0 );
return resultobj;
fail:
return NULL;
}


SWIGINTERN PyObject *_wrap_SBError_GetType(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
lldb::SBError *arg1 = (lldb::SBError *) 0 ;
Expand Down Expand Up @@ -37422,34 +37450,6 @@ SWIGINTERN PyObject *_wrap_SBFrame_IsSwiftThunk(PyObject *self, PyObject *args)
}


SWIGINTERN PyObject *_wrap_SBFrame_GetLanguageSpecificData(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
lldb::SBFrame *arg1 = (lldb::SBFrame *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
lldb::SBStructuredData result;

(void)self;
if (!args) SWIG_fail;
swig_obj[0] = args;
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBFrame, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBFrame_GetLanguageSpecificData" "', argument " "1"" of type '" "lldb::SBFrame const *""'");
}
arg1 = reinterpret_cast< lldb::SBFrame * >(argp1);
{
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
result = ((lldb::SBFrame const *)arg1)->GetLanguageSpecificData();
SWIG_PYTHON_THREAD_END_ALLOW;
}
resultobj = SWIG_NewPointerObj((new lldb::SBStructuredData(result)), SWIGTYPE_p_lldb__SBStructuredData, SWIG_POINTER_OWN | 0 );
return resultobj;
fail:
return NULL;
}


SWIGINTERN PyObject *_wrap_SBFrame_IsInlined__SWIG_0(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {
PyObject *resultobj = 0;
lldb::SBFrame *arg1 = (lldb::SBFrame *) 0 ;
Expand Down Expand Up @@ -37931,6 +37931,34 @@ SWIGINTERN PyObject *_wrap_SBFrame_EvaluateExpression(PyObject *self, PyObject *
}


SWIGINTERN PyObject *_wrap_SBFrame_GetLanguageSpecificData(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
lldb::SBFrame *arg1 = (lldb::SBFrame *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
lldb::SBStructuredData result;

(void)self;
if (!args) SWIG_fail;
swig_obj[0] = args;
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBFrame, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBFrame_GetLanguageSpecificData" "', argument " "1"" of type '" "lldb::SBFrame const *""'");
}
arg1 = reinterpret_cast< lldb::SBFrame * >(argp1);
{
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
result = ((lldb::SBFrame const *)arg1)->GetLanguageSpecificData();
SWIG_PYTHON_THREAD_END_ALLOW;
}
resultobj = SWIG_NewPointerObj((new lldb::SBStructuredData(result)), SWIGTYPE_p_lldb__SBStructuredData, SWIG_POINTER_OWN | 0 );
return resultobj;
fail:
return NULL;
}


SWIGINTERN PyObject *_wrap_SBFrame_GetFrameBlock(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
lldb::SBFrame *arg1 = (lldb::SBFrame *) 0 ;
Expand Down Expand Up @@ -96340,6 +96368,7 @@ static PyMethodDef SwigMethods[] = {
{ "SBError_Fail", _wrap_SBError_Fail, METH_O, "SBError_Fail(SBError self) -> bool"},
{ "SBError_Success", _wrap_SBError_Success, METH_O, "SBError_Success(SBError self) -> bool"},
{ "SBError_GetError", _wrap_SBError_GetError, METH_O, "SBError_GetError(SBError self) -> uint32_t"},
{ "SBError_GetErrorData", _wrap_SBError_GetErrorData, METH_O, "SBError_GetErrorData(SBError self) -> SBStructuredData"},
{ "SBError_GetType", _wrap_SBError_GetType, METH_O, "SBError_GetType(SBError self) -> lldb::ErrorType"},
{ "SBError_SetError", _wrap_SBError_SetError, METH_VARARGS, "SBError_SetError(SBError self, uint32_t err, lldb::ErrorType type)"},
{ "SBError_SetErrorToErrno", _wrap_SBError_SetErrorToErrno, METH_O, "SBError_SetErrorToErrno(SBError self)"},
Expand Down Expand Up @@ -96654,7 +96683,6 @@ static PyMethodDef SwigMethods[] = {
" .\n"
""},
{ "SBFrame_IsSwiftThunk", _wrap_SBFrame_IsSwiftThunk, METH_O, "SBFrame_IsSwiftThunk(SBFrame self) -> bool"},
{ "SBFrame_GetLanguageSpecificData", _wrap_SBFrame_GetLanguageSpecificData, METH_O, "SBFrame_GetLanguageSpecificData(SBFrame self) -> SBStructuredData"},
{ "SBFrame_IsInlined", _wrap_SBFrame_IsInlined, METH_VARARGS, "\n"
"SBFrame_IsInlined(SBFrame self) -> bool\n"
"SBFrame_IsInlined(SBFrame self) -> bool\n"
Expand All @@ -96681,6 +96709,7 @@ static PyMethodDef SwigMethods[] = {
" The version that doesn't supply a 'use_dynamic' value will use the\n"
" target's default.\n"
""},
{ "SBFrame_GetLanguageSpecificData", _wrap_SBFrame_GetLanguageSpecificData, METH_O, "SBFrame_GetLanguageSpecificData(SBFrame self) -> SBStructuredData"},
{ "SBFrame_GetFrameBlock", _wrap_SBFrame_GetFrameBlock, METH_O, "\n"
"SBFrame_GetFrameBlock(SBFrame self) -> SBBlock\n"
"\n"
Expand Down Expand Up @@ -102332,6 +102361,8 @@ SWIG_init(void) {
SWIG_Python_SetConstant(d, "eArgTypeRemotePath",SWIG_From_int(static_cast< int >(lldb::eArgTypeRemotePath)));
SWIG_Python_SetConstant(d, "eArgTypeRemoteFilename",SWIG_From_int(static_cast< int >(lldb::eArgTypeRemoteFilename)));
SWIG_Python_SetConstant(d, "eArgTypeModule",SWIG_From_int(static_cast< int >(lldb::eArgTypeModule)));
SWIG_Python_SetConstant(d, "eArgTypeCPUName",SWIG_From_int(static_cast< int >(lldb::eArgTypeCPUName)));
SWIG_Python_SetConstant(d, "eArgTypeCPUFeatures",SWIG_From_int(static_cast< int >(lldb::eArgTypeCPUFeatures)));
SWIG_Python_SetConstant(d, "eArgTypeLastArg",SWIG_From_int(static_cast< int >(lldb::eArgTypeLastArg)));
SWIG_Python_SetConstant(d, "eSymbolTypeAny",SWIG_From_int(static_cast< int >(lldb::eSymbolTypeAny)));
SWIG_Python_SetConstant(d, "eSymbolTypeInvalid",SWIG_From_int(static_cast< int >(lldb::eSymbolTypeInvalid)));
Expand Down
16 changes: 12 additions & 4 deletions lldb/bindings/python/static-binding/lldb.py
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,10 @@ def lldb_iter(obj, getsize, getelem):

eArgTypeModule = _lldb.eArgTypeModule

eArgTypeCPUName = _lldb.eArgTypeCPUName

eArgTypeCPUFeatures = _lldb.eArgTypeCPUFeatures

eArgTypeLastArg = _lldb.eArgTypeLastArg

eSymbolTypeAny = _lldb.eSymbolTypeAny
Expand Down Expand Up @@ -5425,6 +5429,10 @@ def GetError(self):
r"""GetError(SBError self) -> uint32_t"""
return _lldb.SBError_GetError(self)

def GetErrorData(self):
r"""GetErrorData(SBError self) -> SBStructuredData"""
return _lldb.SBError_GetErrorData(self)

def GetType(self):
r"""GetType(SBError self) -> lldb::ErrorType"""
return _lldb.SBError_GetType(self)
Expand Down Expand Up @@ -6435,10 +6443,6 @@ def IsSwiftThunk(self):
r"""IsSwiftThunk(SBFrame self) -> bool"""
return _lldb.SBFrame_IsSwiftThunk(self)

def GetLanguageSpecificData(self):
r"""GetLanguageSpecificData(SBFrame self) -> SBStructuredData"""
return _lldb.SBFrame_GetLanguageSpecificData(self)

def IsInlined(self, *args):
r"""
IsInlined(SBFrame self) -> bool
Expand Down Expand Up @@ -6477,6 +6481,10 @@ def EvaluateExpression(self, *args):
"""
return _lldb.SBFrame_EvaluateExpression(self, *args)

def GetLanguageSpecificData(self):
r"""GetLanguageSpecificData(SBFrame self) -> SBStructuredData"""
return _lldb.SBFrame_GetLanguageSpecificData(self)

def GetFrameBlock(self):
r"""
GetFrameBlock(SBFrame self) -> SBBlock
Expand Down
5 changes: 5 additions & 0 deletions lldb/include/lldb/API/SBError.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,13 @@ class LLDB_API SBError {

bool Success() const;

/// Get the error code.
uint32_t GetError() const;

/// Get the error in machine-readable form. Particularly useful for
/// compiler diagnostics.
SBStructuredData GetErrorData() const;

lldb::ErrorType GetType() const;

void SetError(uint32_t err, lldb::ErrorType type);
Expand Down
1 change: 1 addition & 0 deletions lldb/include/lldb/API/SBStructuredData.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class SBStructuredData {
friend class SBLaunchInfo;
friend class SBDebugger;
friend class SBFrame;
friend class SBError;
friend class SBTarget;
friend class SBProcess;
friend class SBThread;
Expand Down
14 changes: 10 additions & 4 deletions lldb/include/lldb/Utility/DiagnosticsRendering.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,25 @@ struct DiagnosticDetail {
std::string rendered;
};

StructuredData::ObjectSP Serialize(llvm::ArrayRef<DiagnosticDetail> details);

void RenderDiagnosticDetails(Stream &stream,
std::optional<uint16_t> offset_in_command,
bool show_inline,
llvm::ArrayRef<DiagnosticDetail> details);

class DiagnosticError
: public llvm::ErrorInfo<DiagnosticError, CloneableECError> {
public:
using llvm::ErrorInfo<DiagnosticError, CloneableECError>::ErrorInfo;
DiagnosticError(std::error_code ec) : ErrorInfo(ec) {}
lldb::ErrorType GetErrorType() const override;
virtual llvm::ArrayRef<DiagnosticDetail> GetDetails() const = 0;
StructuredData::ObjectSP GetAsStructuredData() const override {
return Serialize(GetDetails());
}
static char ID;
};

void RenderDiagnosticDetails(Stream &stream,
std::optional<uint16_t> offset_in_command,
bool show_inline,
llvm::ArrayRef<DiagnosticDetail> details);
} // namespace lldb_private
#endif
6 changes: 6 additions & 0 deletions lldb/include/lldb/Utility/Status.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define LLDB_UTILITY_STATUS_H

#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "llvm/ADT/StringRef.h"
Expand Down Expand Up @@ -38,6 +39,7 @@ class CloneableError
CloneableError() : ErrorInfo() {}
virtual std::unique_ptr<CloneableError> Clone() const = 0;
virtual lldb::ErrorType GetErrorType() const = 0;
virtual StructuredData::ObjectSP GetAsStructuredData() const = 0;
static char ID;
};

Expand All @@ -49,6 +51,7 @@ class CloneableECError
std::error_code convertToErrorCode() const override { return EC; }
void log(llvm::raw_ostream &OS) const override { OS << EC.message(); }
lldb::ErrorType GetErrorType() const override;
virtual StructuredData::ObjectSP GetAsStructuredData() const override;
static char ID;

protected:
Expand Down Expand Up @@ -183,6 +186,9 @@ class Status {
/// NULL otherwise.
const char *AsCString(const char *default_error_str = "unknown error") const;

/// Get the error in machine-readable form.
StructuredData::ObjectSP GetAsStructuredData() const;

/// Clear the object state.
///
/// Reverts the state of this object to contain a generic success value and
Expand Down
14 changes: 14 additions & 0 deletions lldb/source/API/SBError.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "lldb/API/SBError.h"
#include "Utils.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStructuredData.h"
#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Utility/Instrumentation.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/VASPrintf.h"
Expand Down Expand Up @@ -97,6 +99,18 @@ uint32_t SBError::GetError() const {
return err;
}

SBStructuredData SBError::GetErrorData() const {
LLDB_INSTRUMENT_VA(this);

SBStructuredData sb_data;
if (!m_opaque_up)
return sb_data;

StructuredData::ObjectSP data(m_opaque_up->GetAsStructuredData());
sb_data.m_impl_up->SetObjectSP(data);
return sb_data;
}

ErrorType SBError::GetType() const {
LLDB_INSTRUMENT_VA(this);

Expand Down
52 changes: 1 addition & 51 deletions lldb/source/Interpreter/CommandReturnObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,57 +145,7 @@ std::string CommandReturnObject::GetErrorString(bool with_diagnostics) {
}

StructuredData::ObjectSP CommandReturnObject::GetErrorData() {
auto make_array = []() { return std::make_unique<StructuredData::Array>(); };
auto make_bool = [](bool b) {
return std::make_unique<StructuredData::Boolean>(b);
};
auto make_dict = []() {
return std::make_unique<StructuredData::Dictionary>();
};
auto make_int = [](unsigned i) {
return std::make_unique<StructuredData::UnsignedInteger>(i);
};
auto make_string = [](llvm::StringRef s) {
return std::make_unique<StructuredData::String>(s);
};
auto dict_up = make_dict();
dict_up->AddItem("version", make_int(1));
auto array_up = make_array();
for (const DiagnosticDetail &diag : m_diagnostics) {
auto detail_up = make_dict();
if (auto &sloc = diag.source_location) {
auto sloc_up = make_dict();
sloc_up->AddItem("file", make_string(sloc->file.GetPath()));
sloc_up->AddItem("line", make_int(sloc->line));
sloc_up->AddItem("length", make_int(sloc->length));
sloc_up->AddItem("hidden", make_bool(sloc->hidden));
sloc_up->AddItem("in_user_input", make_bool(sloc->in_user_input));
detail_up->AddItem("source_location", std::move(sloc_up));
}
llvm::StringRef severity = "unknown";
switch (diag.severity) {
case lldb::eSeverityError:
severity = "error";
break;
case lldb::eSeverityWarning:
severity = "warning";
break;
case lldb::eSeverityInfo:
severity = "note";
break;
}
detail_up->AddItem("severity", make_string(severity));
detail_up->AddItem("message", make_string(diag.message));
detail_up->AddItem("rendered", make_string(diag.rendered));
array_up->AddItem(std::move(detail_up));
}
dict_up->AddItem("details", std::move(array_up));
if (auto stream_sp = m_err_stream.GetStreamAtIndex(eStreamStringIndex)) {
auto text = std::static_pointer_cast<StreamString>(stream_sp)->GetString();
if (!text.empty())
dict_up->AddItem("text", make_string(text));
}
return dict_up;
return Serialize(m_diagnostics);
}

// Similar to AppendError, but do not prepend 'Status: ' to message, and don't
Expand Down
Loading