blob: 2117213ecc67b90752f9a3ea242cc1f1292e0172 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Error.cpp -----------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
Charles Davis322fc842013-08-27 06:13:56 +000011#ifdef __APPLE__
Charles Davis510938e2013-08-27 05:04:57 +000012#include <mach/mach.h>
Charles Davis322fc842013-08-27 06:13:56 +000013#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014
15// C++ Includes
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000016#include <cerrno>
17#include <cstdarg>
18
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019// Other libraries and framework includes
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000020#include "llvm/ADT/SmallVector.h"
21
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/Log.h"
Zachary Turnerf343968f2016-08-09 23:06:08 +000024#include "lldb/Host/PosixApi.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000025#include "lldb/Utility/Error.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027using namespace lldb;
28using namespace lldb_private;
29
Kate Stoneb9c1b512016-09-06 20:57:50 +000030Error::Error() : m_code(0), m_type(eErrorTypeInvalid), m_string() {}
Greg Claytonca512b32011-01-14 04:54:56 +000031
Kate Stoneb9c1b512016-09-06 20:57:50 +000032Error::Error(ValueType err, ErrorType type)
33 : m_code(err), m_type(type), m_string() {}
Greg Claytonca512b32011-01-14 04:54:56 +000034
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000035Error::Error(const Error &rhs) = default;
Greg Claytonca512b32011-01-14 04:54:56 +000036
Kate Stoneb9c1b512016-09-06 20:57:50 +000037Error::Error(const char *format, ...)
38 : m_code(0), m_type(eErrorTypeInvalid), m_string() {
39 va_list args;
40 va_start(args, format);
41 SetErrorToGenericError();
42 SetErrorStringWithVarArg(format, args);
43 va_end(args);
Enrico Granataf2bbf712011-07-15 02:26:42 +000044}
45
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046//----------------------------------------------------------------------
47// Assignment operator
48//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000049const Error &Error::operator=(const Error &rhs) {
50 if (this != &rhs) {
51 m_code = rhs.m_code;
52 m_type = rhs.m_type;
53 m_string = rhs.m_string;
54 }
55 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056}
57
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058//----------------------------------------------------------------------
59// Assignment operator
60//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000061const Error &Error::operator=(uint32_t err) {
62 m_code = err;
63 m_type = eErrorTypeMachKernel;
64 m_string.clear();
65 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066}
67
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000068Error::~Error() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069
70//----------------------------------------------------------------------
71// Get the error value as a NULL C string. The error string will be
72// fetched and cached on demand. The cached error string value will
73// remain until the error value is changed or cleared.
74//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000075const char *Error::AsCString(const char *default_error_str) const {
76 if (Success())
77 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 if (m_string.empty()) {
80 const char *s = nullptr;
81 switch (m_type) {
82 case eErrorTypeMachKernel:
83#if defined(__APPLE__)
84 s = ::mach_error_string(m_code);
Eli Friedman6eb685c2010-06-10 23:45:58 +000085#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +000086 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 case eErrorTypePOSIX:
89 s = ::strerror(m_code);
90 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000091
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 default:
93 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000094 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000095 if (s != nullptr)
96 m_string.assign(s);
97 }
98 if (m_string.empty()) {
99 if (default_error_str)
100 m_string.assign(default_error_str);
101 else
102 return nullptr; // User wanted a nullptr string back...
103 }
104 return m_string.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105}
106
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000107//----------------------------------------------------------------------
108// Clear the error and any cached error string that it might contain.
109//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110void Error::Clear() {
111 m_code = 0;
112 m_type = eErrorTypeInvalid;
113 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000114}
115
116//----------------------------------------------------------------------
117// Access the error value.
118//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119Error::ValueType Error::GetError() const { return m_code; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000120
121//----------------------------------------------------------------------
122// Access the error type.
123//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124ErrorType Error::GetType() const { return m_type; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000125
126//----------------------------------------------------------------------
Ed Maste75500e72016-07-19 15:28:02 +0000127// Returns true if this object contains a value that describes an
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128// error or otherwise non-success result.
129//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130bool Error::Fail() const { return m_code != 0; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131
132//----------------------------------------------------------------------
133// Log the error given a string with format. If the this object
134// contains an error code, update the error string to contain the
135// "error: " followed by the formatted string, followed by the error
136// value and any string that describes the current error. This
137// allows more context to be given to an error string that remains
138// cached in this object. Logging always occurs even when the error
139// code contains a non-error value.
140//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141void Error::PutToLog(Log *log, const char *format, ...) {
142 char *arg_msg = nullptr;
143 va_list args;
144 va_start(args, format);
145 ::vasprintf(&arg_msg, format, args);
146 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148 if (arg_msg != nullptr) {
149 if (Fail()) {
150 const char *err_str = AsCString();
151 if (err_str == nullptr)
152 err_str = "???";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str,
155 m_code);
156 if (log != nullptr)
157 log->Error("%s", m_string.c_str());
158 } else {
159 if (log != nullptr)
160 log->Printf("%s err = 0x%8.8x", arg_msg, m_code);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162 ::free(arg_msg);
163 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000164}
165
166//----------------------------------------------------------------------
167// Log the error given a string with format. If the this object
168// contains an error code, update the error string to contain the
169// "error: " followed by the formatted string, followed by the error
170// value and any string that describes the current error. This
171// allows more context to be given to an error string that remains
172// cached in this object. Logging only occurs even when the error
173// code contains a error value.
174//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000175void Error::LogIfError(Log *log, const char *format, ...) {
176 if (Fail()) {
177 char *arg_msg = nullptr;
178 va_list args;
179 va_start(args, format);
180 ::vasprintf(&arg_msg, format, args);
181 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183 if (arg_msg != nullptr) {
184 const char *err_str = AsCString();
185 if (err_str == nullptr)
186 err_str = "???";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 SetErrorStringWithFormat("%s err = %s (0x%8.8x)", arg_msg, err_str,
189 m_code);
190 if (log != nullptr)
191 log->Error("%s", m_string.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000192
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 ::free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000194 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000195 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196}
197
198//----------------------------------------------------------------------
199// Set accesssor for the error value to "err" and the type to
200// "eErrorTypeMachKernel"
201//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202void Error::SetMachError(uint32_t err) {
203 m_code = err;
204 m_type = eErrorTypeMachKernel;
205 m_string.clear();
206}
207
208void Error::SetExpressionError(lldb::ExpressionResults result,
209 const char *mssg) {
210 m_code = result;
211 m_type = eErrorTypeExpression;
212 m_string = mssg;
213}
214
215int Error::SetExpressionErrorWithFormat(lldb::ExpressionResults result,
216 const char *format, ...) {
217 int length = 0;
218
219 if (format != nullptr && format[0]) {
220 va_list args;
221 va_start(args, format);
222 length = SetErrorStringWithVarArg(format, args);
223 va_end(args);
224 } else {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000225 m_string.clear();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000226 }
227 m_code = result;
228 m_type = eErrorTypeExpression;
229 return length;
Jim Ingham1624a2d2014-05-05 02:26:40 +0000230}
231
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232//----------------------------------------------------------------------
233// Set accesssor for the error value and type.
234//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000235void Error::SetError(ValueType err, ErrorType type) {
236 m_code = err;
237 m_type = type;
238 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000239}
240
241//----------------------------------------------------------------------
242// Update the error value to be "errno" and update the type to
243// be "POSIX".
244//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000245void Error::SetErrorToErrno() {
246 m_code = errno;
247 m_type = eErrorTypePOSIX;
248 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249}
250
251//----------------------------------------------------------------------
252// Update the error value to be LLDB_GENERIC_ERROR and update the type
253// to be "Generic".
254//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000255void Error::SetErrorToGenericError() {
256 m_code = LLDB_GENERIC_ERROR;
257 m_type = eErrorTypeGeneric;
258 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259}
260
261//----------------------------------------------------------------------
262// Set accessor for the error string value for a specific error.
263// This allows any string to be supplied as an error explanation.
264// The error string value will remain until the error value is
265// cleared or a new error value/type is assigned.
266//----------------------------------------------------------------------
Zachary Turnerc1564272016-11-16 21:15:24 +0000267void Error::SetErrorString(llvm::StringRef err_str) {
268 if (!err_str.empty()) {
269 // If we have an error string, we should always at least have an error
270 // set to a generic value.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000271 if (Success())
272 SetErrorToGenericError();
Zachary Turnerc1564272016-11-16 21:15:24 +0000273 }
274 m_string = err_str;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275}
276
277//------------------------------------------------------------------
278/// Set the current error string to a formatted error string.
279///
280/// @param format
281/// A printf style format string
282//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000283int Error::SetErrorStringWithFormat(const char *format, ...) {
284 if (format != nullptr && format[0]) {
285 va_list args;
286 va_start(args, format);
287 int length = SetErrorStringWithVarArg(format, args);
288 va_end(args);
289 return length;
290 } else {
291 m_string.clear();
292 }
293 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294}
295
Kate Stoneb9c1b512016-09-06 20:57:50 +0000296int Error::SetErrorStringWithVarArg(const char *format, va_list args) {
297 if (format != nullptr && format[0]) {
298 // If we have an error string, we should always at least have
299 // an error set to a generic value.
300 if (Success())
301 SetErrorToGenericError();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000302
Kate Stoneb9c1b512016-09-06 20:57:50 +0000303 // Try and fit our error into a 1024 byte buffer first...
304 llvm::SmallVector<char, 1024> buf;
305 buf.resize(1024);
306 // Copy in case our first call to vsnprintf doesn't fit into our
307 // allocated buffer above
308 va_list copy_args;
309 va_copy(copy_args, args);
310 unsigned length = ::vsnprintf(buf.data(), buf.size(), format, args);
311 if (length >= buf.size()) {
312 // The error formatted string didn't fit into our buffer, resize it
313 // to the exact needed size, and retry
314 buf.resize(length + 1);
315 length = ::vsnprintf(buf.data(), buf.size(), format, copy_args);
316 va_end(copy_args);
317 assert(length < buf.size());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000319 m_string.assign(buf.data(), length);
320 va_end(args);
321 return length;
322 } else {
323 m_string.clear();
324 }
325 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326}
327
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328//----------------------------------------------------------------------
329// Returns true if the error code in this object is considered a
330// successful return value.
331//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000332bool Error::Success() const { return m_code == 0; }
Jim Ingham4e5c8212013-06-07 22:09:53 +0000333
Kate Stoneb9c1b512016-09-06 20:57:50 +0000334bool Error::WasInterrupted() const {
335 return (m_type == eErrorTypePOSIX && m_code == EINTR);
Jim Ingham4e5c8212013-06-07 22:09:53 +0000336}