1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "common_throws.h" 18 19 #include <sstream> 20 21 #include "art_field-inl.h" 22 #include "art_method-inl.h" 23 #include "base/logging.h" 24 #include "class_linker-inl.h" 25 #include "dex_file-inl.h" 26 #include "dex_instruction-inl.h" 27 #include "invoke_type.h" 28 #include "mirror/class-inl.h" 29 #include "mirror/object-inl.h" 30 #include "mirror/object_array-inl.h" 31 #include "thread.h" 32 #include "verifier/method_verifier.h" 33 34 namespace art { 35 36 static void AddReferrerLocation(std::ostream& os, mirror::Class* referrer) 37 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 38 if (referrer != nullptr) { 39 std::string location(referrer->GetLocation()); 40 if (!location.empty()) { 41 os << " (declaration of '" << PrettyDescriptor(referrer) 42 << "' appears in " << location << ")"; 43 } 44 } 45 } 46 47 static void ThrowException(const char* exception_descriptor, 48 mirror::Class* referrer, const char* fmt, va_list* args = nullptr) 49 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 50 std::ostringstream msg; 51 if (args != nullptr) { 52 std::string vmsg; 53 StringAppendV(&vmsg, fmt, *args); 54 msg << vmsg; 55 } else { 56 msg << fmt; 57 } 58 AddReferrerLocation(msg, referrer); 59 Thread* self = Thread::Current(); 60 self->ThrowNewException(exception_descriptor, msg.str().c_str()); 61 } 62 63 static void ThrowWrappedException(const char* exception_descriptor, 64 mirror::Class* referrer, const char* fmt, va_list* args = nullptr) 65 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 66 std::ostringstream msg; 67 if (args != nullptr) { 68 std::string vmsg; 69 StringAppendV(&vmsg, fmt, *args); 70 msg << vmsg; 71 } else { 72 msg << fmt; 73 } 74 AddReferrerLocation(msg, referrer); 75 Thread* self = Thread::Current(); 76 self->ThrowNewWrappedException(exception_descriptor, msg.str().c_str()); 77 } 78 79 // AbstractMethodError 80 81 void ThrowAbstractMethodError(ArtMethod* method) { 82 ThrowException("Ljava/lang/AbstractMethodError;", nullptr, 83 StringPrintf("abstract method \"%s\"", 84 PrettyMethod(method).c_str()).c_str()); 85 } 86 87 // ArithmeticException 88 89 void ThrowArithmeticExceptionDivideByZero() { 90 ThrowException("Ljava/lang/ArithmeticException;", nullptr, "divide by zero"); 91 } 92 93 // ArrayIndexOutOfBoundsException 94 95 void ThrowArrayIndexOutOfBoundsException(int index, int length) { 96 ThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", nullptr, 97 StringPrintf("length=%d; index=%d", length, index).c_str()); 98 } 99 100 // ArrayStoreException 101 102 void ThrowArrayStoreException(mirror::Class* element_class, mirror::Class* array_class) { 103 ThrowException("Ljava/lang/ArrayStoreException;", nullptr, 104 StringPrintf("%s cannot be stored in an array of type %s", 105 PrettyDescriptor(element_class).c_str(), 106 PrettyDescriptor(array_class).c_str()).c_str()); 107 } 108 109 // ClassCastException 110 111 void ThrowClassCastException(mirror::Class* dest_type, mirror::Class* src_type) { 112 ThrowException("Ljava/lang/ClassCastException;", nullptr, 113 StringPrintf("%s cannot be cast to %s", 114 PrettyDescriptor(src_type).c_str(), 115 PrettyDescriptor(dest_type).c_str()).c_str()); 116 } 117 118 void ThrowClassCastException(const char* msg) { 119 ThrowException("Ljava/lang/ClassCastException;", nullptr, msg); 120 } 121 122 // ClassCircularityError 123 124 void ThrowClassCircularityError(mirror::Class* c) { 125 std::ostringstream msg; 126 msg << PrettyDescriptor(c); 127 ThrowException("Ljava/lang/ClassCircularityError;", c, msg.str().c_str()); 128 } 129 130 // ClassFormatError 131 132 void ThrowClassFormatError(mirror::Class* referrer, const char* fmt, ...) { 133 va_list args; 134 va_start(args, fmt); 135 ThrowException("Ljava/lang/ClassFormatError;", referrer, fmt, &args); 136 va_end(args);} 137 138 // IllegalAccessError 139 140 void ThrowIllegalAccessErrorClass(mirror::Class* referrer, mirror::Class* accessed) { 141 std::ostringstream msg; 142 msg << "Illegal class access: '" << PrettyDescriptor(referrer) << "' attempting to access '" 143 << PrettyDescriptor(accessed) << "'"; 144 ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 145 } 146 147 void ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class* referrer, mirror::Class* accessed, 148 ArtMethod* called, 149 InvokeType type) { 150 std::ostringstream msg; 151 msg << "Illegal class access ('" << PrettyDescriptor(referrer) << "' attempting to access '" 152 << PrettyDescriptor(accessed) << "') in attempt to invoke " << type 153 << " method " << PrettyMethod(called).c_str(); 154 ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 155 } 156 157 void ThrowIllegalAccessErrorMethod(mirror::Class* referrer, ArtMethod* accessed) { 158 std::ostringstream msg; 159 msg << "Method '" << PrettyMethod(accessed) << "' is inaccessible to class '" 160 << PrettyDescriptor(referrer) << "'"; 161 ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 162 } 163 164 void ThrowIllegalAccessErrorField(mirror::Class* referrer, ArtField* accessed) { 165 std::ostringstream msg; 166 msg << "Field '" << PrettyField(accessed, false) << "' is inaccessible to class '" 167 << PrettyDescriptor(referrer) << "'"; 168 ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 169 } 170 171 void ThrowIllegalAccessErrorFinalField(ArtMethod* referrer, ArtField* accessed) { 172 std::ostringstream msg; 173 msg << "Final field '" << PrettyField(accessed, false) << "' cannot be written to by method '" 174 << PrettyMethod(referrer) << "'"; 175 ThrowException("Ljava/lang/IllegalAccessError;", 176 referrer != nullptr ? referrer->GetDeclaringClass() : nullptr, 177 msg.str().c_str()); 178 } 179 180 void ThrowIllegalAccessError(mirror::Class* referrer, const char* fmt, ...) { 181 va_list args; 182 va_start(args, fmt); 183 ThrowException("Ljava/lang/IllegalAccessError;", referrer, fmt, &args); 184 va_end(args); 185 } 186 187 // IllegalAccessException 188 189 void ThrowIllegalAccessException(const char* msg) { 190 ThrowException("Ljava/lang/IllegalAccessException;", nullptr, msg); 191 } 192 193 // IllegalArgumentException 194 195 void ThrowIllegalArgumentException(const char* msg) { 196 ThrowException("Ljava/lang/IllegalArgumentException;", nullptr, msg); 197 } 198 199 200 // IncompatibleClassChangeError 201 202 void ThrowIncompatibleClassChangeError(InvokeType expected_type, InvokeType found_type, 203 ArtMethod* method, ArtMethod* referrer) { 204 std::ostringstream msg; 205 msg << "The method '" << PrettyMethod(method) << "' was expected to be of type " 206 << expected_type << " but instead was found to be of type " << found_type; 207 ThrowException("Ljava/lang/IncompatibleClassChangeError;", 208 referrer != nullptr ? referrer->GetDeclaringClass() : nullptr, 209 msg.str().c_str()); 210 } 211 212 void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(ArtMethod* interface_method, 213 mirror::Object* this_object, 214 ArtMethod* referrer) { 215 // Referrer is calling interface_method on this_object, however, the interface_method isn't 216 // implemented by this_object. 217 CHECK(this_object != nullptr); 218 std::ostringstream msg; 219 msg << "Class '" << PrettyDescriptor(this_object->GetClass()) 220 << "' does not implement interface '" 221 << PrettyDescriptor(interface_method->GetDeclaringClass()) 222 << "' in call to '" << PrettyMethod(interface_method) << "'"; 223 ThrowException("Ljava/lang/IncompatibleClassChangeError;", 224 referrer != nullptr ? referrer->GetDeclaringClass() : nullptr, 225 msg.str().c_str()); 226 } 227 228 void ThrowIncompatibleClassChangeErrorField(ArtField* resolved_field, bool is_static, 229 ArtMethod* referrer) { 230 std::ostringstream msg; 231 msg << "Expected '" << PrettyField(resolved_field) << "' to be a " 232 << (is_static ? "static" : "instance") << " field" << " rather than a " 233 << (is_static ? "instance" : "static") << " field"; 234 ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer->GetDeclaringClass(), 235 msg.str().c_str()); 236 } 237 238 void ThrowIncompatibleClassChangeError(mirror::Class* referrer, const char* fmt, ...) { 239 va_list args; 240 va_start(args, fmt); 241 ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer, fmt, &args); 242 va_end(args); 243 } 244 245 // IOException 246 247 void ThrowIOException(const char* fmt, ...) { 248 va_list args; 249 va_start(args, fmt); 250 ThrowException("Ljava/io/IOException;", nullptr, fmt, &args); 251 va_end(args); 252 } 253 254 void ThrowWrappedIOException(const char* fmt, ...) { 255 va_list args; 256 va_start(args, fmt); 257 ThrowWrappedException("Ljava/io/IOException;", nullptr, fmt, &args); 258 va_end(args); 259 } 260 261 // LinkageError 262 263 void ThrowLinkageError(mirror::Class* referrer, const char* fmt, ...) { 264 va_list args; 265 va_start(args, fmt); 266 ThrowException("Ljava/lang/LinkageError;", referrer, fmt, &args); 267 va_end(args); 268 } 269 270 void ThrowWrappedLinkageError(mirror::Class* referrer, const char* fmt, ...) { 271 va_list args; 272 va_start(args, fmt); 273 ThrowWrappedException("Ljava/lang/LinkageError;", referrer, fmt, &args); 274 va_end(args); 275 } 276 277 // NegativeArraySizeException 278 279 void ThrowNegativeArraySizeException(int size) { 280 ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr, 281 StringPrintf("%d", size).c_str()); 282 } 283 284 void ThrowNegativeArraySizeException(const char* msg) { 285 ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr, msg); 286 } 287 288 // NoSuchFieldError 289 290 void ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c, 291 const StringPiece& type, const StringPiece& name) { 292 std::ostringstream msg; 293 std::string temp; 294 msg << "No " << scope << "field " << name << " of type " << type 295 << " in class " << c->GetDescriptor(&temp) << " or its superclasses"; 296 ThrowException("Ljava/lang/NoSuchFieldError;", c, msg.str().c_str()); 297 } 298 299 void ThrowNoSuchFieldException(mirror::Class* c, const StringPiece& name) { 300 std::ostringstream msg; 301 std::string temp; 302 msg << "No field " << name << " in class " << c->GetDescriptor(&temp); 303 ThrowException("Ljava/lang/NoSuchFieldException;", c, msg.str().c_str()); 304 } 305 306 // NoSuchMethodError 307 308 void ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name, 309 const Signature& signature) { 310 std::ostringstream msg; 311 std::string temp; 312 msg << "No " << type << " method " << name << signature 313 << " in class " << c->GetDescriptor(&temp) << " or its super classes"; 314 ThrowException("Ljava/lang/NoSuchMethodError;", c, msg.str().c_str()); 315 } 316 317 void ThrowNoSuchMethodError(uint32_t method_idx) { 318 ArtMethod* method = Thread::Current()->GetCurrentMethod(nullptr); 319 mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); 320 const DexFile& dex_file = *dex_cache->GetDexFile(); 321 std::ostringstream msg; 322 msg << "No method '" << PrettyMethod(method_idx, dex_file, true) << "'"; 323 ThrowException("Ljava/lang/NoSuchMethodError;", 324 method->GetDeclaringClass(), msg.str().c_str()); 325 } 326 327 // NullPointerException 328 329 void ThrowNullPointerExceptionForFieldAccess(ArtField* field, bool is_read) { 330 std::ostringstream msg; 331 msg << "Attempt to " << (is_read ? "read from" : "write to") 332 << " field '" << PrettyField(field, true) << "' on a null object reference"; 333 ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str()); 334 } 335 336 static void ThrowNullPointerExceptionForMethodAccessImpl(uint32_t method_idx, 337 const DexFile& dex_file, 338 InvokeType type) 339 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 340 std::ostringstream msg; 341 msg << "Attempt to invoke " << type << " method '" 342 << PrettyMethod(method_idx, dex_file, true) << "' on a null object reference"; 343 ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str()); 344 } 345 346 void ThrowNullPointerExceptionForMethodAccess(uint32_t method_idx, 347 InvokeType type) { 348 mirror::DexCache* dex_cache = 349 Thread::Current()->GetCurrentMethod(nullptr)->GetDeclaringClass()->GetDexCache(); 350 const DexFile& dex_file = *dex_cache->GetDexFile(); 351 ThrowNullPointerExceptionForMethodAccessImpl(method_idx, dex_file, type); 352 } 353 354 void ThrowNullPointerExceptionForMethodAccess(ArtMethod* method, 355 InvokeType type) { 356 mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache(); 357 const DexFile& dex_file = *dex_cache->GetDexFile(); 358 ThrowNullPointerExceptionForMethodAccessImpl(method->GetDexMethodIndex(), 359 dex_file, type); 360 } 361 362 void ThrowNullPointerExceptionFromDexPC() { 363 uint32_t throw_dex_pc; 364 ArtMethod* method = Thread::Current()->GetCurrentMethod(&throw_dex_pc); 365 const DexFile::CodeItem* code = method->GetCodeItem(); 366 CHECK_LT(throw_dex_pc, code->insns_size_in_code_units_); 367 const Instruction* instr = Instruction::At(&code->insns_[throw_dex_pc]); 368 switch (instr->Opcode()) { 369 case Instruction::INVOKE_DIRECT: 370 ThrowNullPointerExceptionForMethodAccess(instr->VRegB_35c(), kDirect); 371 break; 372 case Instruction::INVOKE_DIRECT_RANGE: 373 ThrowNullPointerExceptionForMethodAccess(instr->VRegB_3rc(), kDirect); 374 break; 375 case Instruction::INVOKE_VIRTUAL: 376 ThrowNullPointerExceptionForMethodAccess(instr->VRegB_35c(), kVirtual); 377 break; 378 case Instruction::INVOKE_VIRTUAL_RANGE: 379 ThrowNullPointerExceptionForMethodAccess(instr->VRegB_3rc(), kVirtual); 380 break; 381 case Instruction::INVOKE_INTERFACE: 382 ThrowNullPointerExceptionForMethodAccess(instr->VRegB_35c(), kInterface); 383 break; 384 case Instruction::INVOKE_INTERFACE_RANGE: 385 ThrowNullPointerExceptionForMethodAccess(instr->VRegB_3rc(), kInterface); 386 break; 387 case Instruction::INVOKE_VIRTUAL_QUICK: 388 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { 389 // Since we replaced the method index, we ask the verifier to tell us which 390 // method is invoked at this location. 391 ArtMethod* invoked_method = 392 verifier::MethodVerifier::FindInvokedMethodAtDexPc(method, throw_dex_pc); 393 if (invoked_method != nullptr) { 394 // NPE with precise message. 395 ThrowNullPointerExceptionForMethodAccess(invoked_method, kVirtual); 396 } else { 397 // NPE with imprecise message. 398 ThrowNullPointerException("Attempt to invoke a virtual method on a null object reference"); 399 } 400 break; 401 } 402 case Instruction::IGET: 403 case Instruction::IGET_WIDE: 404 case Instruction::IGET_OBJECT: 405 case Instruction::IGET_BOOLEAN: 406 case Instruction::IGET_BYTE: 407 case Instruction::IGET_CHAR: 408 case Instruction::IGET_SHORT: { 409 ArtField* field = 410 Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), method, false); 411 ThrowNullPointerExceptionForFieldAccess(field, true /* read */); 412 break; 413 } 414 case Instruction::IGET_QUICK: 415 case Instruction::IGET_BOOLEAN_QUICK: 416 case Instruction::IGET_BYTE_QUICK: 417 case Instruction::IGET_CHAR_QUICK: 418 case Instruction::IGET_SHORT_QUICK: 419 case Instruction::IGET_WIDE_QUICK: 420 case Instruction::IGET_OBJECT_QUICK: { 421 // Since we replaced the field index, we ask the verifier to tell us which 422 // field is accessed at this location. 423 ArtField* field = 424 verifier::MethodVerifier::FindAccessedFieldAtDexPc(method, throw_dex_pc); 425 if (field != nullptr) { 426 // NPE with precise message. 427 ThrowNullPointerExceptionForFieldAccess(field, true /* read */); 428 } else { 429 // NPE with imprecise message. 430 ThrowNullPointerException("Attempt to read from a field on a null object reference"); 431 } 432 break; 433 } 434 case Instruction::IPUT: 435 case Instruction::IPUT_WIDE: 436 case Instruction::IPUT_OBJECT: 437 case Instruction::IPUT_BOOLEAN: 438 case Instruction::IPUT_BYTE: 439 case Instruction::IPUT_CHAR: 440 case Instruction::IPUT_SHORT: { 441 ArtField* field = 442 Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), method, false); 443 ThrowNullPointerExceptionForFieldAccess(field, false /* write */); 444 break; 445 } 446 case Instruction::IPUT_QUICK: 447 case Instruction::IPUT_BOOLEAN_QUICK: 448 case Instruction::IPUT_BYTE_QUICK: 449 case Instruction::IPUT_CHAR_QUICK: 450 case Instruction::IPUT_SHORT_QUICK: 451 case Instruction::IPUT_WIDE_QUICK: 452 case Instruction::IPUT_OBJECT_QUICK: { 453 // Since we replaced the field index, we ask the verifier to tell us which 454 // field is accessed at this location. 455 ArtField* field = 456 verifier::MethodVerifier::FindAccessedFieldAtDexPc(method, throw_dex_pc); 457 if (field != nullptr) { 458 // NPE with precise message. 459 ThrowNullPointerExceptionForFieldAccess(field, false /* write */); 460 } else { 461 // NPE with imprecise message. 462 ThrowNullPointerException("Attempt to write to a field on a null object reference"); 463 } 464 break; 465 } 466 case Instruction::AGET: 467 case Instruction::AGET_WIDE: 468 case Instruction::AGET_OBJECT: 469 case Instruction::AGET_BOOLEAN: 470 case Instruction::AGET_BYTE: 471 case Instruction::AGET_CHAR: 472 case Instruction::AGET_SHORT: 473 ThrowException("Ljava/lang/NullPointerException;", nullptr, 474 "Attempt to read from null array"); 475 break; 476 case Instruction::APUT: 477 case Instruction::APUT_WIDE: 478 case Instruction::APUT_OBJECT: 479 case Instruction::APUT_BOOLEAN: 480 case Instruction::APUT_BYTE: 481 case Instruction::APUT_CHAR: 482 case Instruction::APUT_SHORT: 483 ThrowException("Ljava/lang/NullPointerException;", nullptr, 484 "Attempt to write to null array"); 485 break; 486 case Instruction::ARRAY_LENGTH: 487 ThrowException("Ljava/lang/NullPointerException;", nullptr, 488 "Attempt to get length of null array"); 489 break; 490 default: { 491 // TODO: We should have covered all the cases where we expect a NPE above, this 492 // message/logging is so we can improve any cases we've missed in the future. 493 const DexFile* dex_file = 494 method->GetDeclaringClass()->GetDexCache()->GetDexFile(); 495 ThrowException("Ljava/lang/NullPointerException;", nullptr, 496 StringPrintf("Null pointer exception during instruction '%s'", 497 instr->DumpString(dex_file).c_str()).c_str()); 498 break; 499 } 500 } 501 } 502 503 void ThrowNullPointerException(const char* msg) { 504 ThrowException("Ljava/lang/NullPointerException;", nullptr, msg); 505 } 506 507 // RuntimeException 508 509 void ThrowRuntimeException(const char* fmt, ...) { 510 va_list args; 511 va_start(args, fmt); 512 ThrowException("Ljava/lang/RuntimeException;", nullptr, fmt, &args); 513 va_end(args); 514 } 515 516 // VerifyError 517 518 void ThrowVerifyError(mirror::Class* referrer, const char* fmt, ...) { 519 va_list args; 520 va_start(args, fmt); 521 ThrowException("Ljava/lang/VerifyError;", referrer, fmt, &args); 522 va_end(args); 523 } 524 525 } // namespace art 526