1 //===-- 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 11 #include <errno.h> 12 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/Error.h" 17 #include "lldb/Core/Log.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include <cstdarg> 20 #include <cstdlib> 21 #include <cstring> 22 23 #if defined (__arm__) && defined (__APPLE__) 24 #include <SpringBoardServices/SpringBoardServer.h> 25 #endif 26 27 using namespace lldb; 28 using namespace lldb_private; 29 30 Error::Error (): 31 m_code (0), 32 m_type (eErrorTypeInvalid), 33 m_string () 34 { 35 } 36 37 //---------------------------------------------------------------------- 38 // Default constructor 39 //---------------------------------------------------------------------- 40 Error::Error(ValueType err, ErrorType type) : 41 m_code (err), 42 m_type (type), 43 m_string () 44 { 45 } 46 47 Error::Error (const Error &rhs) : 48 m_code (rhs.m_code), 49 m_type (rhs.m_type), 50 m_string (rhs.m_string) 51 { 52 } 53 54 Error::Error (const char* err_str): 55 m_code (0), 56 m_type (eErrorTypeInvalid), 57 m_string () 58 { 59 SetErrorString(err_str); 60 } 61 62 //---------------------------------------------------------------------- 63 // Assignment operator 64 //---------------------------------------------------------------------- 65 const Error& 66 Error::operator = (const Error& rhs) 67 { 68 if (this != &rhs) 69 { 70 m_code = rhs.m_code; 71 m_type = rhs.m_type; 72 m_string = rhs.m_string; 73 } 74 return *this; 75 } 76 77 78 //---------------------------------------------------------------------- 79 // Assignment operator 80 //---------------------------------------------------------------------- 81 const Error& 82 Error::operator = (uint32_t err) 83 { 84 m_code = err; 85 m_type = eErrorTypeMachKernel; 86 m_string.clear(); 87 return *this; 88 } 89 90 Error::~Error() 91 { 92 } 93 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 //---------------------------------------------------------------------- 99 const char * 100 Error::AsCString(const char *default_error_str) const 101 { 102 if (Success()) 103 return NULL; 104 105 if (m_string.empty()) 106 { 107 const char *s = NULL; 108 switch (m_type) 109 { 110 case eErrorTypeMachKernel: 111 #if defined (__APPLE__) 112 s = ::mach_error_string (m_code); 113 #endif 114 break; 115 116 case eErrorTypePOSIX: 117 s = ::strerror (m_code); 118 break; 119 120 default: 121 break; 122 } 123 if (s) 124 m_string.assign(s); 125 } 126 if (m_string.empty()) 127 { 128 if (default_error_str) 129 m_string.assign(default_error_str); 130 else 131 return NULL; // User wanted a NULL string back... 132 } 133 return m_string.c_str(); 134 } 135 136 137 //---------------------------------------------------------------------- 138 // Clear the error and any cached error string that it might contain. 139 //---------------------------------------------------------------------- 140 void 141 Error::Clear () 142 { 143 m_code = 0; 144 m_type = eErrorTypeGeneric; 145 m_string.clear(); 146 } 147 148 //---------------------------------------------------------------------- 149 // Access the error value. 150 //---------------------------------------------------------------------- 151 Error::ValueType 152 Error::GetError () const 153 { 154 return m_code; 155 } 156 157 //---------------------------------------------------------------------- 158 // Access the error type. 159 //---------------------------------------------------------------------- 160 ErrorType 161 Error::GetType () const 162 { 163 return m_type; 164 } 165 166 //---------------------------------------------------------------------- 167 // Retuns true if this object contains an value that describes an 168 // error or otherwise non-success result. 169 //---------------------------------------------------------------------- 170 bool 171 Error::Fail () const 172 { 173 return m_code != 0; 174 } 175 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 //---------------------------------------------------------------------- 185 void 186 Error::PutToLog (Log *log, const char *format, ...) 187 { 188 char *arg_msg = NULL; 189 va_list args; 190 va_start (args, format); 191 ::vasprintf (&arg_msg, format, args); 192 va_end (args); 193 194 if (arg_msg != NULL) 195 { 196 if (Fail()) 197 { 198 const char *err_str = AsCString(); 199 if (err_str == NULL) 200 err_str = "???"; 201 202 SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_code); 203 if (log) 204 log->Error("%s", m_string.c_str()); 205 } 206 else 207 { 208 if (log) 209 log->Printf("%s err = 0x%8.8x", arg_msg, m_code); 210 } 211 ::free (arg_msg); 212 } 213 } 214 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 //---------------------------------------------------------------------- 224 void 225 Error::LogIfError (Log *log, const char *format, ...) 226 { 227 if (Fail()) 228 { 229 char *arg_msg = NULL; 230 va_list args; 231 va_start (args, format); 232 ::vasprintf (&arg_msg, format, args); 233 va_end (args); 234 235 if (arg_msg != NULL) 236 { 237 const char *err_str = AsCString(); 238 if (err_str == NULL) 239 err_str = "???"; 240 241 SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_code); 242 if (log) 243 log->Error("%s", m_string.c_str()); 244 245 ::free (arg_msg); 246 } 247 } 248 } 249 250 //---------------------------------------------------------------------- 251 // Set accesssor for the error value to "err" and the type to 252 // "eErrorTypeMachKernel" 253 //---------------------------------------------------------------------- 254 void 255 Error::SetMachError (uint32_t err) 256 { 257 m_code = err; 258 m_type = eErrorTypeMachKernel; 259 m_string.clear(); 260 } 261 262 //---------------------------------------------------------------------- 263 // Set accesssor for the error value and type. 264 //---------------------------------------------------------------------- 265 void 266 Error::SetError (ValueType err, ErrorType type) 267 { 268 m_code = err; 269 m_type = type; 270 m_string.clear(); 271 } 272 273 //---------------------------------------------------------------------- 274 // Update the error value to be "errno" and update the type to 275 // be "POSIX". 276 //---------------------------------------------------------------------- 277 void 278 Error::SetErrorToErrno() 279 { 280 m_code = errno; 281 m_type = eErrorTypePOSIX; 282 m_string.clear(); 283 } 284 285 //---------------------------------------------------------------------- 286 // Update the error value to be LLDB_GENERIC_ERROR and update the type 287 // to be "Generic". 288 //---------------------------------------------------------------------- 289 void 290 Error::SetErrorToGenericError () 291 { 292 m_code = LLDB_GENERIC_ERROR; 293 m_type = eErrorTypeGeneric; 294 m_string.clear(); 295 } 296 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 //---------------------------------------------------------------------- 303 void 304 Error::SetErrorString (const char *err_str) 305 { 306 if (err_str && err_str[0]) 307 { 308 // If we have an error string, we should always at least have 309 // an error set to a generic value. 310 if (Success()) 311 SetErrorToGenericError(); 312 m_string = err_str; 313 } 314 else 315 m_string.clear(); 316 } 317 318 //------------------------------------------------------------------ 319 /// Set the current error string to a formatted error string. 320 /// 321 /// @param format 322 /// A printf style format string 323 //------------------------------------------------------------------ 324 int 325 Error::SetErrorStringWithFormat (const char *format, ...) 326 { 327 if (format && format[0]) 328 { 329 va_list args; 330 va_start (args, format); 331 int length = SetErrorStringWithVarArg (format, args); 332 va_end (args); 333 return length; 334 } 335 else 336 { 337 m_string.clear(); 338 } 339 return 0; 340 } 341 342 int 343 Error::SetErrorStringWithVarArg (const char *format, va_list args) 344 { 345 if (format && format[0]) 346 { 347 // If we have an error string, we should always at least have 348 // an error set to a generic value. 349 if (Success()) 350 SetErrorToGenericError(); 351 352 // Try and fit our error into a 1024 byte buffer first... 353 llvm::SmallVector<char, 1024> buf; 354 buf.resize(1024); 355 // Copy in case our first call to vsnprintf doesn't fit into our 356 // allocated buffer above 357 va_list copy_args; 358 va_copy (copy_args, args); 359 unsigned length = ::vsnprintf (buf.data(), buf.size(), format, args); 360 if (length >= buf.size()) 361 { 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); 366 va_end (copy_args); 367 assert (length < buf.size()); 368 } 369 m_string.assign(buf.data(), length); 370 va_end (args); 371 return length; 372 } 373 else 374 { 375 m_string.clear(); 376 } 377 return 0; 378 } 379 380 381 //---------------------------------------------------------------------- 382 // Returns true if the error code in this object is considered a 383 // successful return value. 384 //---------------------------------------------------------------------- 385 bool 386 Error::Success() const 387 { 388 return m_code == 0; 389 } 390 391 bool 392 Error::WasInterrupted() const 393 { 394 if (m_type == eErrorTypePOSIX && m_code == EINTR) 395 return true; 396 else 397 return false; 398 } 399 400