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 //===----------------------------------------------------------------------===//
12 #include <mach/mach.h>
16 // Other libraries and framework includes
18 #include "lldb/Core/Error.h"
19 #include "lldb/Core/Log.h"
20 #include "llvm/ADT/SmallVector.h"
24 #if defined (__arm__) && defined (__APPLE__)
25 #include <SpringBoardServices/SpringBoardServer.h>
29 using namespace lldb_private;
33 m_type (eErrorTypeInvalid),
38 //----------------------------------------------------------------------
39 // Default constructor
40 //----------------------------------------------------------------------
41 Error::Error(ValueType err, ErrorType type) :
48 Error::Error (const Error &rhs) :
51 m_string (rhs.m_string)
55 Error::Error (const char* format, ...):
57 m_type (eErrorTypeInvalid),
61 va_start (args, format);
62 SetErrorToGenericError ();
63 SetErrorStringWithVarArg (format, args);
67 //----------------------------------------------------------------------
68 // Assignment operator
69 //----------------------------------------------------------------------
71 Error::operator = (const Error& rhs)
77 m_string = rhs.m_string;
83 //----------------------------------------------------------------------
84 // Assignment operator
85 //----------------------------------------------------------------------
87 Error::operator = (uint32_t err)
90 m_type = eErrorTypeMachKernel;
99 //----------------------------------------------------------------------
100 // Get the error value as a NULL C string. The error string will be
101 // fetched and cached on demand. The cached error string value will
102 // remain until the error value is changed or cleared.
103 //----------------------------------------------------------------------
105 Error::AsCString(const char *default_error_str) const
110 if (m_string.empty())
112 const char *s = NULL;
115 case eErrorTypeMachKernel:
116 #if defined (__APPLE__)
117 s = ::mach_error_string (m_code);
121 case eErrorTypePOSIX:
122 s = ::strerror (m_code);
131 if (m_string.empty())
133 if (default_error_str)
134 m_string.assign(default_error_str);
136 return NULL; // User wanted a NULL string back...
138 return m_string.c_str();
142 //----------------------------------------------------------------------
143 // Clear the error and any cached error string that it might contain.
144 //----------------------------------------------------------------------
149 m_type = eErrorTypeGeneric;
153 //----------------------------------------------------------------------
154 // Access the error value.
155 //----------------------------------------------------------------------
157 Error::GetError () const
162 //----------------------------------------------------------------------
163 // Access the error type.
164 //----------------------------------------------------------------------
166 Error::GetType () const
171 //----------------------------------------------------------------------
172 // Retuns true if this object contains an value that describes an
173 // error or otherwise non-success result.
174 //----------------------------------------------------------------------
181 //----------------------------------------------------------------------
182 // Log the error given a string with format. If the this object
183 // contains an error code, update the error string to contain the
184 // "error: " followed by the formatted string, followed by the error
185 // value and any string that describes the current error. This
186 // allows more context to be given to an error string that remains
187 // cached in this object. Logging always occurs even when the error
188 // code contains a non-error value.
189 //----------------------------------------------------------------------
191 Error::PutToLog (Log *log, const char *format, ...)
193 char *arg_msg = NULL;
195 va_start (args, format);
196 ::vasprintf (&arg_msg, format, args);
203 const char *err_str = AsCString();
207 SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
209 log->Error("%s", m_string.c_str());
214 log->Printf("%s err = 0x%8.8x", arg_msg, m_code);
220 //----------------------------------------------------------------------
221 // Log the error given a string with format. If the this object
222 // contains an error code, update the error string to contain the
223 // "error: " followed by the formatted string, followed by the error
224 // value and any string that describes the current error. This
225 // allows more context to be given to an error string that remains
226 // cached in this object. Logging only occurs even when the error
227 // code contains a error value.
228 //----------------------------------------------------------------------
230 Error::LogIfError (Log *log, const char *format, ...)
234 char *arg_msg = NULL;
236 va_start (args, format);
237 ::vasprintf (&arg_msg, format, args);
242 const char *err_str = AsCString();
246 SetErrorStringWithFormat("%s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
248 log->Error("%s", m_string.c_str());
255 //----------------------------------------------------------------------
256 // Set accesssor for the error value to "err" and the type to
257 // "eErrorTypeMachKernel"
258 //----------------------------------------------------------------------
260 Error::SetMachError (uint32_t err)
263 m_type = eErrorTypeMachKernel;
267 //----------------------------------------------------------------------
268 // Set accesssor for the error value and type.
269 //----------------------------------------------------------------------
271 Error::SetError (ValueType err, ErrorType type)
278 //----------------------------------------------------------------------
279 // Update the error value to be "errno" and update the type to
281 //----------------------------------------------------------------------
283 Error::SetErrorToErrno()
286 m_type = eErrorTypePOSIX;
290 //----------------------------------------------------------------------
291 // Update the error value to be LLDB_GENERIC_ERROR and update the type
293 //----------------------------------------------------------------------
295 Error::SetErrorToGenericError ()
297 m_code = LLDB_GENERIC_ERROR;
298 m_type = eErrorTypeGeneric;
302 //----------------------------------------------------------------------
303 // Set accessor for the error string value for a specific error.
304 // This allows any string to be supplied as an error explanation.
305 // The error string value will remain until the error value is
306 // cleared or a new error value/type is assigned.
307 //----------------------------------------------------------------------
309 Error::SetErrorString (const char *err_str)
311 if (err_str && err_str[0])
313 // If we have an error string, we should always at least have
314 // an error set to a generic value.
316 SetErrorToGenericError();
323 //------------------------------------------------------------------
324 /// Set the current error string to a formatted error string.
327 /// A printf style format string
328 //------------------------------------------------------------------
330 Error::SetErrorStringWithFormat (const char *format, ...)
332 if (format && format[0])
335 va_start (args, format);
336 int length = SetErrorStringWithVarArg (format, args);
348 Error::SetErrorStringWithVarArg (const char *format, va_list args)
350 if (format && format[0])
352 // If we have an error string, we should always at least have
353 // an error set to a generic value.
355 SetErrorToGenericError();
357 // Try and fit our error into a 1024 byte buffer first...
358 llvm::SmallVector<char, 1024> buf;
360 // Copy in case our first call to vsnprintf doesn't fit into our
361 // allocated buffer above
363 va_copy (copy_args, args);
364 unsigned length = ::vsnprintf (buf.data(), buf.size(), format, args);
365 if (length >= buf.size())
367 // The error formatted string didn't fit into our buffer, resize it
368 // to the exact needed size, and retry
369 buf.resize(length + 1);
370 length = ::vsnprintf (buf.data(), buf.size(), format, copy_args);
372 assert (length < buf.size());
374 m_string.assign(buf.data(), length);
386 //----------------------------------------------------------------------
387 // Returns true if the error code in this object is considered a
388 // successful return value.
389 //----------------------------------------------------------------------
391 Error::Success() const
397 Error::WasInterrupted() const
399 if (m_type == eErrorTypePOSIX && m_code == EINTR)