1254721Semaste//===-- Error.cpp -----------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste// C Includes
11263363Semaste#ifdef __APPLE__
12263363Semaste#include <mach/mach.h>
13263363Semaste#endif
14254721Semaste
15254721Semaste// C++ Includes
16254721Semaste// Other libraries and framework includes
17254721Semaste// Project includes
18254721Semaste#include "lldb/Core/Error.h"
19254721Semaste#include "lldb/Core/Log.h"
20254721Semaste#include "llvm/ADT/SmallVector.h"
21263363Semaste#include <cerrno>
22254721Semaste#include <cstdarg>
23254721Semaste
24254721Semaste#if defined (__arm__) && defined (__APPLE__)
25254721Semaste#include <SpringBoardServices/SpringBoardServer.h>
26254721Semaste#endif
27254721Semaste
28254721Semasteusing namespace lldb;
29254721Semasteusing namespace lldb_private;
30254721Semaste
31254721SemasteError::Error ():
32254721Semaste    m_code (0),
33254721Semaste    m_type (eErrorTypeInvalid),
34254721Semaste    m_string ()
35254721Semaste{
36254721Semaste}
37254721Semaste
38254721Semaste//----------------------------------------------------------------------
39254721Semaste// Default constructor
40254721Semaste//----------------------------------------------------------------------
41254721SemasteError::Error(ValueType err, ErrorType type) :
42254721Semaste    m_code (err),
43254721Semaste    m_type (type),
44254721Semaste    m_string ()
45254721Semaste{
46254721Semaste}
47254721Semaste
48254721SemasteError::Error (const Error &rhs) :
49254721Semaste    m_code (rhs.m_code),
50254721Semaste    m_type (rhs.m_type),
51254721Semaste    m_string (rhs.m_string)
52254721Semaste{
53254721Semaste}
54254721Semaste
55263363SemasteError::Error (const char* format, ...):
56254721Semaste    m_code (0),
57254721Semaste    m_type (eErrorTypeInvalid),
58254721Semaste    m_string ()
59254721Semaste{
60263363Semaste    va_list args;
61263363Semaste    va_start (args, format);
62263363Semaste    SetErrorToGenericError ();
63263363Semaste    SetErrorStringWithVarArg (format, args);
64263363Semaste    va_end (args);
65254721Semaste}
66254721Semaste
67254721Semaste//----------------------------------------------------------------------
68254721Semaste// Assignment operator
69254721Semaste//----------------------------------------------------------------------
70254721Semasteconst Error&
71254721SemasteError::operator = (const Error& rhs)
72254721Semaste{
73254721Semaste    if (this != &rhs)
74254721Semaste    {
75254721Semaste        m_code = rhs.m_code;
76254721Semaste        m_type = rhs.m_type;
77254721Semaste        m_string = rhs.m_string;
78254721Semaste    }
79254721Semaste    return *this;
80254721Semaste}
81254721Semaste
82254721Semaste
83254721Semaste//----------------------------------------------------------------------
84254721Semaste// Assignment operator
85254721Semaste//----------------------------------------------------------------------
86254721Semasteconst Error&
87254721SemasteError::operator = (uint32_t err)
88254721Semaste{
89254721Semaste    m_code = err;
90254721Semaste    m_type = eErrorTypeMachKernel;
91254721Semaste    m_string.clear();
92254721Semaste    return *this;
93254721Semaste}
94254721Semaste
95254721SemasteError::~Error()
96254721Semaste{
97254721Semaste}
98254721Semaste
99254721Semaste//----------------------------------------------------------------------
100254721Semaste// Get the error value as a NULL C string. The error string will be
101254721Semaste// fetched and cached on demand. The cached error string value will
102254721Semaste// remain until the error value is changed or cleared.
103254721Semaste//----------------------------------------------------------------------
104254721Semasteconst char *
105254721SemasteError::AsCString(const char *default_error_str) const
106254721Semaste{
107254721Semaste    if (Success())
108254721Semaste        return NULL;
109254721Semaste
110254721Semaste    if (m_string.empty())
111254721Semaste    {
112254721Semaste        const char *s = NULL;
113254721Semaste        switch (m_type)
114254721Semaste        {
115254721Semaste        case eErrorTypeMachKernel:
116254721Semaste#if defined (__APPLE__)
117254721Semaste            s = ::mach_error_string (m_code);
118254721Semaste#endif
119254721Semaste            break;
120254721Semaste
121254721Semaste        case eErrorTypePOSIX:
122254721Semaste            s = ::strerror (m_code);
123254721Semaste            break;
124254721Semaste
125254721Semaste        default:
126254721Semaste            break;
127254721Semaste        }
128254721Semaste        if (s)
129254721Semaste            m_string.assign(s);
130254721Semaste    }
131254721Semaste    if (m_string.empty())
132254721Semaste    {
133254721Semaste        if (default_error_str)
134254721Semaste            m_string.assign(default_error_str);
135254721Semaste        else
136254721Semaste            return NULL;    // User wanted a NULL string back...
137254721Semaste    }
138254721Semaste    return m_string.c_str();
139254721Semaste}
140254721Semaste
141254721Semaste
142254721Semaste//----------------------------------------------------------------------
143254721Semaste// Clear the error and any cached error string that it might contain.
144254721Semaste//----------------------------------------------------------------------
145254721Semastevoid
146254721SemasteError::Clear ()
147254721Semaste{
148254721Semaste    m_code = 0;
149254721Semaste    m_type = eErrorTypeGeneric;
150254721Semaste    m_string.clear();
151254721Semaste}
152254721Semaste
153254721Semaste//----------------------------------------------------------------------
154254721Semaste// Access the error value.
155254721Semaste//----------------------------------------------------------------------
156254721SemasteError::ValueType
157254721SemasteError::GetError () const
158254721Semaste{
159254721Semaste    return m_code;
160254721Semaste}
161254721Semaste
162254721Semaste//----------------------------------------------------------------------
163254721Semaste// Access the error type.
164254721Semaste//----------------------------------------------------------------------
165254721SemasteErrorType
166254721SemasteError::GetType () const
167254721Semaste{
168254721Semaste    return m_type;
169254721Semaste}
170254721Semaste
171254721Semaste//----------------------------------------------------------------------
172254721Semaste// Retuns true if this object contains an value that describes an
173254721Semaste// error or otherwise non-success result.
174254721Semaste//----------------------------------------------------------------------
175254721Semastebool
176254721SemasteError::Fail () const
177254721Semaste{
178254721Semaste    return m_code != 0;
179254721Semaste}
180254721Semaste
181254721Semaste//----------------------------------------------------------------------
182254721Semaste// Log the error given a string with format. If the this object
183254721Semaste// contains an error code, update the error string to contain the
184254721Semaste// "error: " followed by the formatted string, followed by the error
185254721Semaste// value and any string that describes the current error. This
186254721Semaste// allows more context to be given to an error string that remains
187254721Semaste// cached in this object. Logging always occurs even when the error
188254721Semaste// code contains a non-error value.
189254721Semaste//----------------------------------------------------------------------
190254721Semastevoid
191254721SemasteError::PutToLog (Log *log, const char *format, ...)
192254721Semaste{
193254721Semaste    char *arg_msg = NULL;
194254721Semaste    va_list args;
195254721Semaste    va_start (args, format);
196254721Semaste    ::vasprintf (&arg_msg, format, args);
197254721Semaste    va_end (args);
198254721Semaste
199254721Semaste    if (arg_msg != NULL)
200254721Semaste    {
201254721Semaste        if (Fail())
202254721Semaste        {
203254721Semaste            const char *err_str = AsCString();
204254721Semaste            if (err_str == NULL)
205254721Semaste                err_str = "???";
206254721Semaste
207254721Semaste            SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
208254721Semaste            if (log)
209254721Semaste                log->Error("%s", m_string.c_str());
210254721Semaste        }
211254721Semaste        else
212254721Semaste        {
213254721Semaste            if (log)
214254721Semaste                log->Printf("%s err = 0x%8.8x", arg_msg, m_code);
215254721Semaste        }
216254721Semaste        ::free (arg_msg);
217254721Semaste    }
218254721Semaste}
219254721Semaste
220254721Semaste//----------------------------------------------------------------------
221254721Semaste// Log the error given a string with format. If the this object
222254721Semaste// contains an error code, update the error string to contain the
223254721Semaste// "error: " followed by the formatted string, followed by the error
224254721Semaste// value and any string that describes the current error. This
225254721Semaste// allows more context to be given to an error string that remains
226254721Semaste// cached in this object. Logging only occurs even when the error
227254721Semaste// code contains a error value.
228254721Semaste//----------------------------------------------------------------------
229254721Semastevoid
230254721SemasteError::LogIfError (Log *log, const char *format, ...)
231254721Semaste{
232254721Semaste    if (Fail())
233254721Semaste    {
234254721Semaste        char *arg_msg = NULL;
235254721Semaste        va_list args;
236254721Semaste        va_start (args, format);
237254721Semaste        ::vasprintf (&arg_msg, format, args);
238254721Semaste        va_end (args);
239254721Semaste
240254721Semaste        if (arg_msg != NULL)
241254721Semaste        {
242254721Semaste            const char *err_str = AsCString();
243254721Semaste            if (err_str == NULL)
244254721Semaste                err_str = "???";
245254721Semaste
246263363Semaste            SetErrorStringWithFormat("%s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
247254721Semaste            if (log)
248254721Semaste                log->Error("%s", m_string.c_str());
249254721Semaste
250254721Semaste            ::free (arg_msg);
251254721Semaste        }
252254721Semaste    }
253254721Semaste}
254254721Semaste
255254721Semaste//----------------------------------------------------------------------
256254721Semaste// Set accesssor for the error value to "err" and the type to
257254721Semaste// "eErrorTypeMachKernel"
258254721Semaste//----------------------------------------------------------------------
259254721Semastevoid
260254721SemasteError::SetMachError (uint32_t err)
261254721Semaste{
262254721Semaste    m_code = err;
263254721Semaste    m_type = eErrorTypeMachKernel;
264254721Semaste    m_string.clear();
265254721Semaste}
266254721Semaste
267254721Semaste//----------------------------------------------------------------------
268254721Semaste// Set accesssor for the error value and type.
269254721Semaste//----------------------------------------------------------------------
270254721Semastevoid
271254721SemasteError::SetError (ValueType err, ErrorType type)
272254721Semaste{
273254721Semaste    m_code = err;
274254721Semaste    m_type = type;
275254721Semaste    m_string.clear();
276254721Semaste}
277254721Semaste
278254721Semaste//----------------------------------------------------------------------
279254721Semaste// Update the error value to be "errno" and update the type to
280254721Semaste// be "POSIX".
281254721Semaste//----------------------------------------------------------------------
282254721Semastevoid
283254721SemasteError::SetErrorToErrno()
284254721Semaste{
285254721Semaste    m_code = errno;
286254721Semaste    m_type = eErrorTypePOSIX;
287254721Semaste    m_string.clear();
288254721Semaste}
289254721Semaste
290254721Semaste//----------------------------------------------------------------------
291254721Semaste// Update the error value to be LLDB_GENERIC_ERROR and update the type
292254721Semaste// to be "Generic".
293254721Semaste//----------------------------------------------------------------------
294254721Semastevoid
295254721SemasteError::SetErrorToGenericError ()
296254721Semaste{
297254721Semaste    m_code = LLDB_GENERIC_ERROR;
298254721Semaste    m_type = eErrorTypeGeneric;
299254721Semaste    m_string.clear();
300254721Semaste}
301254721Semaste
302254721Semaste//----------------------------------------------------------------------
303254721Semaste// Set accessor for the error string value for a specific error.
304254721Semaste// This allows any string to be supplied as an error explanation.
305254721Semaste// The error string value will remain until the error value is
306254721Semaste// cleared or a new error value/type is assigned.
307254721Semaste//----------------------------------------------------------------------
308254721Semastevoid
309254721SemasteError::SetErrorString (const char *err_str)
310254721Semaste{
311254721Semaste    if (err_str && err_str[0])
312254721Semaste    {
313254721Semaste        // If we have an error string, we should always at least have
314254721Semaste        // an error set to a generic value.
315254721Semaste        if (Success())
316254721Semaste            SetErrorToGenericError();
317254721Semaste        m_string = err_str;
318254721Semaste    }
319254721Semaste    else
320254721Semaste        m_string.clear();
321254721Semaste}
322254721Semaste
323254721Semaste//------------------------------------------------------------------
324254721Semaste/// Set the current error string to a formatted error string.
325254721Semaste///
326254721Semaste/// @param format
327254721Semaste///     A printf style format string
328254721Semaste//------------------------------------------------------------------
329254721Semasteint
330254721SemasteError::SetErrorStringWithFormat (const char *format, ...)
331254721Semaste{
332254721Semaste    if (format && format[0])
333254721Semaste    {
334254721Semaste        va_list args;
335254721Semaste        va_start (args, format);
336254721Semaste        int length = SetErrorStringWithVarArg (format, args);
337254721Semaste        va_end (args);
338254721Semaste        return length;
339254721Semaste    }
340254721Semaste    else
341254721Semaste    {
342254721Semaste        m_string.clear();
343254721Semaste    }
344254721Semaste    return 0;
345254721Semaste}
346254721Semaste
347254721Semasteint
348254721SemasteError::SetErrorStringWithVarArg (const char *format, va_list args)
349254721Semaste{
350254721Semaste    if (format && format[0])
351254721Semaste    {
352254721Semaste        // If we have an error string, we should always at least have
353254721Semaste        // an error set to a generic value.
354254721Semaste        if (Success())
355254721Semaste            SetErrorToGenericError();
356254721Semaste
357254721Semaste        // Try and fit our error into a 1024 byte buffer first...
358254721Semaste        llvm::SmallVector<char, 1024> buf;
359254721Semaste        buf.resize(1024);
360254721Semaste        // Copy in case our first call to vsnprintf doesn't fit into our
361254721Semaste        // allocated buffer above
362254721Semaste        va_list copy_args;
363254721Semaste        va_copy (copy_args, args);
364254721Semaste        unsigned length = ::vsnprintf (buf.data(), buf.size(), format, args);
365254721Semaste        if (length >= buf.size())
366254721Semaste        {
367254721Semaste            // The error formatted string didn't fit into our buffer, resize it
368254721Semaste            // to the exact needed size, and retry
369254721Semaste            buf.resize(length + 1);
370254721Semaste            length = ::vsnprintf (buf.data(), buf.size(), format, copy_args);
371254721Semaste            va_end (copy_args);
372254721Semaste            assert (length < buf.size());
373254721Semaste        }
374254721Semaste        m_string.assign(buf.data(), length);
375254721Semaste        va_end (args);
376254721Semaste        return length;
377254721Semaste    }
378254721Semaste    else
379254721Semaste    {
380254721Semaste        m_string.clear();
381254721Semaste    }
382254721Semaste    return 0;
383254721Semaste}
384254721Semaste
385254721Semaste
386254721Semaste//----------------------------------------------------------------------
387254721Semaste// Returns true if the error code in this object is considered a
388254721Semaste// successful return value.
389254721Semaste//----------------------------------------------------------------------
390254721Semastebool
391254721SemasteError::Success() const
392254721Semaste{
393254721Semaste    return m_code == 0;
394254721Semaste}
395254721Semaste
396254721Semastebool
397254721SemasteError::WasInterrupted() const
398254721Semaste{
399254721Semaste    if (m_type == eErrorTypePOSIX && m_code == EINTR)
400254721Semaste        return true;
401254721Semaste    else
402254721Semaste        return false;
403254721Semaste}
404254721Semaste
405