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