1 //===-- SBError.cpp -------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/API/SBError.h" 10 #include "Utils.h" 11 #include "lldb/API/SBStream.h" 12 #include "lldb/API/SBStructuredData.h" 13 #include "lldb/Core/StructuredDataImpl.h" 14 #include "lldb/Utility/Instrumentation.h" 15 #include "lldb/Utility/Status.h" 16 #include "lldb/Utility/VASPrintf.h" 17 18 #include <cstdarg> 19 20 using namespace lldb; 21 using namespace lldb_private; 22 23 SBError::SBError() { LLDB_INSTRUMENT_VA(this); } 24 25 SBError::SBError(const SBError &rhs) { 26 LLDB_INSTRUMENT_VA(this, rhs); 27 28 if (rhs.m_opaque_up) 29 m_opaque_up = std::make_unique<Status>(rhs.m_opaque_up->Clone()); 30 } 31 32 SBError::SBError(const char *message) { 33 LLDB_INSTRUMENT_VA(this, message); 34 35 SetErrorString(message); 36 } 37 38 SBError::SBError(lldb_private::Status &&status) 39 : m_opaque_up(new Status(std::move(status))) { 40 LLDB_INSTRUMENT_VA(this, status); 41 } 42 43 SBError::~SBError() = default; 44 45 const SBError &SBError::operator=(const SBError &rhs) { 46 LLDB_INSTRUMENT_VA(this, rhs); 47 48 if (this != &rhs) 49 if (rhs.m_opaque_up) 50 m_opaque_up = std::make_unique<Status>(rhs.m_opaque_up->Clone()); 51 52 return *this; 53 } 54 55 const char *SBError::GetCString() const { 56 LLDB_INSTRUMENT_VA(this); 57 58 if (m_opaque_up) 59 return m_opaque_up->AsCString(); 60 return nullptr; 61 } 62 63 void SBError::Clear() { 64 LLDB_INSTRUMENT_VA(this); 65 66 if (m_opaque_up) 67 m_opaque_up->Clear(); 68 } 69 70 bool SBError::Fail() const { 71 LLDB_INSTRUMENT_VA(this); 72 73 bool ret_value = false; 74 if (m_opaque_up) 75 ret_value = m_opaque_up->Fail(); 76 77 78 return ret_value; 79 } 80 81 bool SBError::Success() const { 82 LLDB_INSTRUMENT_VA(this); 83 84 bool ret_value = true; 85 if (m_opaque_up) 86 ret_value = m_opaque_up->Success(); 87 88 return ret_value; 89 } 90 91 uint32_t SBError::GetError() const { 92 LLDB_INSTRUMENT_VA(this); 93 94 uint32_t err = 0; 95 if (m_opaque_up) 96 err = m_opaque_up->GetError(); 97 98 99 return err; 100 } 101 102 SBStructuredData SBError::GetErrorData() const { 103 LLDB_INSTRUMENT_VA(this); 104 105 SBStructuredData sb_data; 106 if (!m_opaque_up) 107 return sb_data; 108 109 StructuredData::ObjectSP data(m_opaque_up->GetAsStructuredData()); 110 sb_data.m_impl_up->SetObjectSP(data); 111 return sb_data; 112 } 113 114 ErrorType SBError::GetType() const { 115 LLDB_INSTRUMENT_VA(this); 116 117 ErrorType err_type = eErrorTypeInvalid; 118 if (m_opaque_up) 119 err_type = m_opaque_up->GetType(); 120 121 return err_type; 122 } 123 124 void SBError::SetError(uint32_t err, ErrorType type) { 125 LLDB_INSTRUMENT_VA(this, err, type); 126 127 CreateIfNeeded(); 128 *m_opaque_up = Status(err, type); 129 } 130 131 void SBError::SetError(Status &&lldb_error) { 132 CreateIfNeeded(); 133 *m_opaque_up = std::move(lldb_error); 134 } 135 136 void SBError::SetErrorToErrno() { 137 LLDB_INSTRUMENT_VA(this); 138 139 CreateIfNeeded(); 140 *m_opaque_up = Status::FromErrno(); 141 } 142 143 void SBError::SetErrorToGenericError() { 144 LLDB_INSTRUMENT_VA(this); 145 146 CreateIfNeeded(); 147 *m_opaque_up = Status(std::string("generic error")); 148 } 149 150 void SBError::SetErrorString(const char *err_str) { 151 LLDB_INSTRUMENT_VA(this, err_str); 152 153 CreateIfNeeded(); 154 *m_opaque_up = Status::FromErrorString(err_str); 155 } 156 157 int SBError::SetErrorStringWithFormat(const char *format, ...) { 158 CreateIfNeeded(); 159 std::string string; 160 va_list args; 161 va_start(args, format); 162 if (format != nullptr && format[0]) { 163 llvm::SmallString<1024> buf; 164 VASprintf(buf, format, args); 165 string = std::string(buf.str()); 166 *m_opaque_up = Status(std::move(string)); 167 } 168 va_end(args); 169 return string.size(); 170 } 171 172 bool SBError::IsValid() const { 173 LLDB_INSTRUMENT_VA(this); 174 return this->operator bool(); 175 } 176 SBError::operator bool() const { 177 LLDB_INSTRUMENT_VA(this); 178 179 return m_opaque_up != nullptr; 180 } 181 182 void SBError::CreateIfNeeded() { 183 if (m_opaque_up == nullptr) 184 m_opaque_up = std::make_unique<Status>(); 185 } 186 187 lldb_private::Status *SBError::operator->() { return m_opaque_up.get(); } 188 189 lldb_private::Status *SBError::get() { return m_opaque_up.get(); } 190 191 lldb_private::Status &SBError::ref() { 192 CreateIfNeeded(); 193 return *m_opaque_up; 194 } 195 196 const lldb_private::Status &SBError::operator*() const { 197 // Be sure to call "IsValid()" before calling this function or it will crash 198 return *m_opaque_up; 199 } 200 201 bool SBError::GetDescription(SBStream &description) { 202 LLDB_INSTRUMENT_VA(this, description); 203 204 if (m_opaque_up) { 205 if (m_opaque_up->Success()) 206 description.Printf("success"); 207 else { 208 const char *err_string = GetCString(); 209 description.Printf("error: %s", 210 (err_string != nullptr ? err_string : "")); 211 } 212 } else 213 description.Printf("error: <NULL>"); 214 215 return true; 216 } 217