1 //===-- Error.cpp -----------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
14 // Other libraries and framework includes
16 #include "lldb/Core/Error.h"
17 #include "lldb/Core/Log.h"
18 #include "llvm/ADT/SmallVector.h"
23 #if defined (__arm__) && defined (__APPLE__)
24 #include <SpringBoardServices/SpringBoardServer.h>
28 using namespace lldb_private;
32 m_type (eErrorTypeInvalid),
37 //----------------------------------------------------------------------
38 // Default constructor
39 //----------------------------------------------------------------------
40 Error::Error(ValueType err, ErrorType type) :
47 Error::Error (const Error &rhs) :
50 m_string (rhs.m_string)
54 Error::Error (const char* err_str):
56 m_type (eErrorTypeInvalid),
59 SetErrorString(err_str);
62 //----------------------------------------------------------------------
63 // Assignment operator
64 //----------------------------------------------------------------------
66 Error::operator = (const Error& rhs)
72 m_string = rhs.m_string;
78 //----------------------------------------------------------------------
79 // Assignment operator
80 //----------------------------------------------------------------------
82 Error::operator = (uint32_t err)
85 m_type = eErrorTypeMachKernel;
94 //----------------------------------------------------------------------
95 // Get the error value as a NULL C string. The error string will be
96 // fetched and cached on demand. The cached error string value will
97 // remain until the error value is changed or cleared.
98 //----------------------------------------------------------------------
100 Error::AsCString(const char *default_error_str) const
105 if (m_string.empty())
107 const char *s = NULL;
110 case eErrorTypeMachKernel:
111 #if defined (__APPLE__)
112 s = ::mach_error_string (m_code);
116 case eErrorTypePOSIX:
117 s = ::strerror (m_code);
126 if (m_string.empty())
128 if (default_error_str)
129 m_string.assign(default_error_str);
131 return NULL; // User wanted a NULL string back...
133 return m_string.c_str();
137 //----------------------------------------------------------------------
138 // Clear the error and any cached error string that it might contain.
139 //----------------------------------------------------------------------
144 m_type = eErrorTypeGeneric;
148 //----------------------------------------------------------------------
149 // Access the error value.
150 //----------------------------------------------------------------------
152 Error::GetError () const
157 //----------------------------------------------------------------------
158 // Access the error type.
159 //----------------------------------------------------------------------
161 Error::GetType () const
166 //----------------------------------------------------------------------
167 // Retuns true if this object contains an value that describes an
168 // error or otherwise non-success result.
169 //----------------------------------------------------------------------
176 //----------------------------------------------------------------------
177 // Log the error given a string with format. If the this object
178 // contains an error code, update the error string to contain the
179 // "error: " followed by the formatted string, followed by the error
180 // value and any string that describes the current error. This
181 // allows more context to be given to an error string that remains
182 // cached in this object. Logging always occurs even when the error
183 // code contains a non-error value.
184 //----------------------------------------------------------------------
186 Error::PutToLog (Log *log, const char *format, ...)
188 char *arg_msg = NULL;
190 va_start (args, format);
191 ::vasprintf (&arg_msg, format, args);
198 const char *err_str = AsCString();
202 SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
204 log->Error("%s", m_string.c_str());
209 log->Printf("%s err = 0x%8.8x", arg_msg, m_code);
215 //----------------------------------------------------------------------
216 // Log the error given a string with format. If the this object
217 // contains an error code, update the error string to contain the
218 // "error: " followed by the formatted string, followed by the error
219 // value and any string that describes the current error. This
220 // allows more context to be given to an error string that remains
221 // cached in this object. Logging only occurs even when the error
222 // code contains a error value.
223 //----------------------------------------------------------------------
225 Error::LogIfError (Log *log, const char *format, ...)
229 char *arg_msg = NULL;
231 va_start (args, format);
232 ::vasprintf (&arg_msg, format, args);
237 const char *err_str = AsCString();
241 SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
243 log->Error("%s", m_string.c_str());
250 //----------------------------------------------------------------------
251 // Set accesssor for the error value to "err" and the type to
252 // "eErrorTypeMachKernel"
253 //----------------------------------------------------------------------
255 Error::SetMachError (uint32_t err)
258 m_type = eErrorTypeMachKernel;
262 //----------------------------------------------------------------------
263 // Set accesssor for the error value and type.
264 //----------------------------------------------------------------------
266 Error::SetError (ValueType err, ErrorType type)
273 //----------------------------------------------------------------------
274 // Update the error value to be "errno" and update the type to
276 //----------------------------------------------------------------------
278 Error::SetErrorToErrno()
281 m_type = eErrorTypePOSIX;
285 //----------------------------------------------------------------------
286 // Update the error value to be LLDB_GENERIC_ERROR and update the type
288 //----------------------------------------------------------------------
290 Error::SetErrorToGenericError ()
292 m_code = LLDB_GENERIC_ERROR;
293 m_type = eErrorTypeGeneric;
297 //----------------------------------------------------------------------
298 // Set accessor for the error string value for a specific error.
299 // This allows any string to be supplied as an error explanation.
300 // The error string value will remain until the error value is
301 // cleared or a new error value/type is assigned.
302 //----------------------------------------------------------------------
304 Error::SetErrorString (const char *err_str)
306 if (err_str && err_str[0])
308 // If we have an error string, we should always at least have
309 // an error set to a generic value.
311 SetErrorToGenericError();
318 //------------------------------------------------------------------
319 /// Set the current error string to a formatted error string.
322 /// A printf style format string
323 //------------------------------------------------------------------
325 Error::SetErrorStringWithFormat (const char *format, ...)
327 if (format && format[0])
330 va_start (args, format);
331 int length = SetErrorStringWithVarArg (format, args);
343 Error::SetErrorStringWithVarArg (const char *format, va_list args)
345 if (format && format[0])
347 // If we have an error string, we should always at least have
348 // an error set to a generic value.
350 SetErrorToGenericError();
352 // Try and fit our error into a 1024 byte buffer first...
353 llvm::SmallVector<char, 1024> buf;
355 // Copy in case our first call to vsnprintf doesn't fit into our
356 // allocated buffer above
358 va_copy (copy_args, args);
359 unsigned length = ::vsnprintf (buf.data(), buf.size(), format, args);
360 if (length >= buf.size())
362 // The error formatted string didn't fit into our buffer, resize it
363 // to the exact needed size, and retry
364 buf.resize(length + 1);
365 length = ::vsnprintf (buf.data(), buf.size(), format, copy_args);
367 assert (length < buf.size());
369 m_string.assign(buf.data(), length);
381 //----------------------------------------------------------------------
382 // Returns true if the error code in this object is considered a
383 // successful return value.
384 //----------------------------------------------------------------------
386 Error::Success() const
392 Error::WasInterrupted() const
394 if (m_type == eErrorTypePOSIX && m_code == EINTR)