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 <android-base/logging.h> 22 #include <android-base/stringprintf.h> 23 24 #include "art_field-inl.h" 25 #include "art_method-inl.h" 26 #include "class_linker-inl.h" 27 #include "debug_print.h" 28 #include "dex/dex_file-inl.h" 29 #include "dex/dex_instruction-inl.h" 30 #include "dex/invoke_type.h" 31 #include "mirror/class-inl.h" 32 #include "mirror/method_type.h" 33 #include "mirror/object-inl.h" 34 #include "mirror/object_array-inl.h" 35 #include "nativehelper/scoped_local_ref.h" 36 #include "obj_ptr-inl.h" 37 #include "thread.h" 38 #include "vdex_file.h" 39 #include "verifier/method_verifier.h" 40 #include "well_known_classes.h" 41 42 namespace art { 43 44 using android::base::StringAppendV; 45 using android::base::StringPrintf; 46 47 static void AddReferrerLocation(std::ostream& os, ObjPtr<mirror::Class> referrer) 48 REQUIRES_SHARED(Locks::mutator_lock_) { 49 if (referrer != nullptr) { 50 std::string location(referrer->GetLocation()); 51 if (!location.empty()) { 52 os << " (declaration of '" << referrer->PrettyDescriptor() 53 << "' appears in " << location << ")"; 54 } 55 } 56 } 57 58 static void ThrowException(const char* exception_descriptor) REQUIRES_SHARED(Locks::mutator_lock_) { 59 Thread* self = Thread::Current(); 60 self->ThrowNewException(exception_descriptor, nullptr); 61 } 62 63 static void ThrowException(const char* exception_descriptor, 64 ObjPtr<mirror::Class> referrer, 65 const char* fmt, 66 va_list* args = nullptr) 67 REQUIRES_SHARED(Locks::mutator_lock_) { 68 std::ostringstream msg; 69 if (args != nullptr) { 70 std::string vmsg; 71 StringAppendV(&vmsg, fmt, *args); 72 msg << vmsg; 73 } else { 74 msg << fmt; 75 } 76 AddReferrerLocation(msg, referrer); 77 Thread* self = Thread::Current(); 78 self->ThrowNewException(exception_descriptor, msg.str().c_str()); 79 } 80 81 static void ThrowWrappedException(const char* exception_descriptor, 82 ObjPtr<mirror::Class> referrer, 83 const char* fmt, 84 va_list* args = nullptr) 85 REQUIRES_SHARED(Locks::mutator_lock_) { 86 std::ostringstream msg; 87 if (args != nullptr) { 88 std::string vmsg; 89 StringAppendV(&vmsg, fmt, *args); 90 msg << vmsg; 91 } else { 92 msg << fmt; 93 } 94 AddReferrerLocation(msg, referrer); 95 Thread* self = Thread::Current(); 96 self->ThrowNewWrappedException(exception_descriptor, msg.str().c_str()); 97 } 98 99 // AbstractMethodError 100 101 void ThrowAbstractMethodError(ArtMethod* method) { 102 ThrowException("Ljava/lang/AbstractMethodError;", nullptr, 103 StringPrintf("abstract method \"%s\"", 104 ArtMethod::PrettyMethod(method).c_str()).c_str()); 105 } 106 107 void ThrowAbstractMethodError(uint32_t method_idx, const DexFile& dex_file) { 108 ThrowException("Ljava/lang/AbstractMethodError;", /* referrer */ nullptr, 109 StringPrintf("abstract method \"%s\"", 110 dex_file.PrettyMethod(method_idx, 111 /* with_signature */ true).c_str()).c_str()); 112 } 113 114 // ArithmeticException 115 116 void ThrowArithmeticExceptionDivideByZero() { 117 ThrowException("Ljava/lang/ArithmeticException;", nullptr, "divide by zero"); 118 } 119 120 // ArrayIndexOutOfBoundsException 121 122 void ThrowArrayIndexOutOfBoundsException(int index, int length) { 123 ThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", nullptr, 124 StringPrintf("length=%d; index=%d", length, index).c_str()); 125 } 126 127 // ArrayStoreException 128 129 void ThrowArrayStoreException(ObjPtr<mirror::Class> element_class, 130 ObjPtr<mirror::Class> array_class) { 131 ThrowException("Ljava/lang/ArrayStoreException;", nullptr, 132 StringPrintf("%s cannot be stored in an array of type %s", 133 mirror::Class::PrettyDescriptor(element_class).c_str(), 134 mirror::Class::PrettyDescriptor(array_class).c_str()).c_str()); 135 } 136 137 // BootstrapMethodError 138 139 void ThrowBootstrapMethodError(const char* fmt, ...) { 140 va_list args; 141 va_start(args, fmt); 142 ThrowException("Ljava/lang/BootstrapMethodError;", nullptr, fmt, &args); 143 va_end(args); 144 } 145 146 void ThrowWrappedBootstrapMethodError(const char* fmt, ...) { 147 va_list args; 148 va_start(args, fmt); 149 ThrowWrappedException("Ljava/lang/BootstrapMethodError;", nullptr, fmt, &args); 150 va_end(args); 151 } 152 153 // ClassCastException 154 155 void ThrowClassCastException(ObjPtr<mirror::Class> dest_type, ObjPtr<mirror::Class> src_type) { 156 DumpB77342775DebugData(dest_type, src_type); 157 ThrowException("Ljava/lang/ClassCastException;", nullptr, 158 StringPrintf("%s cannot be cast to %s", 159 mirror::Class::PrettyDescriptor(src_type).c_str(), 160 mirror::Class::PrettyDescriptor(dest_type).c_str()).c_str()); 161 } 162 163 void ThrowClassCastException(const char* msg) { 164 ThrowException("Ljava/lang/ClassCastException;", nullptr, msg); 165 } 166 167 // ClassCircularityError 168 169 void ThrowClassCircularityError(ObjPtr<mirror::Class> c) { 170 std::ostringstream msg; 171 msg << mirror::Class::PrettyDescriptor(c); 172 ThrowException("Ljava/lang/ClassCircularityError;", c, msg.str().c_str()); 173 } 174 175 void ThrowClassCircularityError(ObjPtr<mirror::Class> c, const char* fmt, ...) { 176 va_list args; 177 va_start(args, fmt); 178 ThrowException("Ljava/lang/ClassCircularityError;", c, fmt, &args); 179 va_end(args); 180 } 181 182 // ClassFormatError 183 184 void ThrowClassFormatError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) { 185 va_list args; 186 va_start(args, fmt); 187 ThrowException("Ljava/lang/ClassFormatError;", referrer, fmt, &args); 188 va_end(args); 189 } 190 191 // IllegalAccessError 192 193 void ThrowIllegalAccessErrorClass(ObjPtr<mirror::Class> referrer, ObjPtr<mirror::Class> accessed) { 194 std::ostringstream msg; 195 msg << "Illegal class access: '" << mirror::Class::PrettyDescriptor(referrer) 196 << "' attempting to access '" << mirror::Class::PrettyDescriptor(accessed) << "'"; 197 ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 198 } 199 200 void ThrowIllegalAccessErrorClassForMethodDispatch(ObjPtr<mirror::Class> referrer, 201 ObjPtr<mirror::Class> accessed, 202 ArtMethod* called, 203 InvokeType type) { 204 std::ostringstream msg; 205 msg << "Illegal class access ('" << mirror::Class::PrettyDescriptor(referrer) 206 << "' attempting to access '" 207 << mirror::Class::PrettyDescriptor(accessed) << "') in attempt to invoke " << type 208 << " method " << ArtMethod::PrettyMethod(called).c_str(); 209 ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 210 } 211 212 void ThrowIllegalAccessErrorMethod(ObjPtr<mirror::Class> referrer, ArtMethod* accessed) { 213 std::ostringstream msg; 214 msg << "Method '" << ArtMethod::PrettyMethod(accessed) << "' is inaccessible to class '" 215 << mirror::Class::PrettyDescriptor(referrer) << "'"; 216 ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 217 } 218 219 void ThrowIllegalAccessErrorField(ObjPtr<mirror::Class> referrer, ArtField* accessed) { 220 std::ostringstream msg; 221 msg << "Field '" << ArtField::PrettyField(accessed, false) << "' is inaccessible to class '" 222 << mirror::Class::PrettyDescriptor(referrer) << "'"; 223 ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str()); 224 } 225 226 void ThrowIllegalAccessErrorFinalField(ArtMethod* referrer, ArtField* accessed) { 227 std::ostringstream msg; 228 msg << "Final field '" << ArtField::PrettyField(accessed, false) 229 << "' cannot be written to by method '" << ArtMethod::PrettyMethod(referrer) << "'"; 230 ThrowException("Ljava/lang/IllegalAccessError;", 231 referrer != nullptr ? referrer->GetDeclaringClass() : nullptr, 232 msg.str().c_str()); 233 } 234 235 void ThrowIllegalAccessError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) { 236 va_list args; 237 va_start(args, fmt); 238 ThrowException("Ljava/lang/IllegalAccessError;", referrer, fmt, &args); 239 va_end(args); 240 } 241 242 // IllegalAccessException 243 244 void ThrowIllegalAccessException(const char* msg) { 245 ThrowException("Ljava/lang/IllegalAccessException;", nullptr, msg); 246 } 247 248 // IllegalArgumentException 249 250 void ThrowIllegalArgumentException(const char* msg) { 251 ThrowException("Ljava/lang/IllegalArgumentException;", nullptr, msg); 252 } 253 254 // IllegalStateException 255 256 void ThrowIllegalStateException(const char* msg) { 257 ThrowException("Ljava/lang/IllegalStateException;", nullptr, msg); 258 } 259 260 // IncompatibleClassChangeError 261 262 void ThrowIncompatibleClassChangeError(InvokeType expected_type, InvokeType found_type, 263 ArtMethod* method, ArtMethod* referrer) { 264 std::ostringstream msg; 265 msg << "The method '" << ArtMethod::PrettyMethod(method) << "' was expected to be of type " 266 << expected_type << " but instead was found to be of type " << found_type; 267 ThrowException("Ljava/lang/IncompatibleClassChangeError;", 268 referrer != nullptr ? referrer->GetDeclaringClass() : nullptr, 269 msg.str().c_str()); 270 } 271 272 void ThrowIncompatibleClassChangeErrorClassForInterfaceSuper(ArtMethod* method, 273 ObjPtr<mirror::Class> target_class, 274 ObjPtr<mirror::Object> this_object, 275 ArtMethod* referrer) { 276 // Referrer is calling interface_method on this_object, however, the interface_method isn't 277 // implemented by this_object. 278 CHECK(this_object != nullptr); 279 std::ostringstream msg; 280 msg << "Class '" << mirror::Class::PrettyDescriptor(this_object->GetClass()) 281 << "' does not implement interface '" << mirror::Class::PrettyDescriptor(target_class) 282 << "' in call to '" 283 << ArtMethod::PrettyMethod(method) << "'"; 284 DumpB77342775DebugData(target_class, this_object->GetClass()); 285 ThrowException("Ljava/lang/IncompatibleClassChangeError;", 286 referrer != nullptr ? referrer->GetDeclaringClass() : nullptr, 287 msg.str().c_str()); 288 } 289 290 void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(ArtMethod* interface_method, 291 ObjPtr<mirror::Object> this_object, 292 ArtMethod* referrer) { 293 // Referrer is calling interface_method on this_object, however, the interface_method isn't 294 // implemented by this_object. 295 CHECK(this_object != nullptr); 296 std::ostringstream msg; 297 msg << "Class '" << mirror::Class::PrettyDescriptor(this_object->GetClass()) 298 << "' does not implement interface '" 299 << mirror::Class::PrettyDescriptor(interface_method->GetDeclaringClass()) 300 << "' in call to '" << ArtMethod::PrettyMethod(interface_method) << "'"; 301 DumpB77342775DebugData(interface_method->GetDeclaringClass(), this_object->GetClass()); 302 ThrowException("Ljava/lang/IncompatibleClassChangeError;", 303 referrer != nullptr ? referrer->GetDeclaringClass() : nullptr, 304 msg.str().c_str()); 305 } 306 307 void ThrowIncompatibleClassChangeErrorField(ArtField* resolved_field, bool is_static, 308 ArtMethod* referrer) { 309 std::ostringstream msg; 310 msg << "Expected '" << ArtField::PrettyField(resolved_field) << "' to be a " 311 << (is_static ? "static" : "instance") << " field" << " rather than a " 312 << (is_static ? "instance" : "static") << " field"; 313 ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer->GetDeclaringClass(), 314 msg.str().c_str()); 315 } 316 317 void ThrowIncompatibleClassChangeError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) { 318 va_list args; 319 va_start(args, fmt); 320 ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer, fmt, &args); 321 va_end(args); 322 } 323 324 void ThrowIncompatibleClassChangeErrorForMethodConflict(ArtMethod* method) { 325 DCHECK(method != nullptr); 326 ThrowException("Ljava/lang/IncompatibleClassChangeError;", 327 /*referrer*/nullptr, 328 StringPrintf("Conflicting default method implementations %s", 329 ArtMethod::PrettyMethod(method).c_str()).c_str()); 330 } 331 332 // IndexOutOfBoundsException 333 334 void ThrowIndexOutOfBoundsException(int index, int length) { 335 ThrowException("Ljava/lang/IndexOutOfBoundsException;", nullptr, 336 StringPrintf("length=%d; index=%d", length, index).c_str()); 337 } 338 339 // InternalError 340 341 void ThrowInternalError(const char* fmt, ...) { 342 va_list args; 343 va_start(args, fmt); 344 ThrowException("Ljava/lang/InternalError;", nullptr, fmt, &args); 345 va_end(args); 346 } 347 348 // IOException 349 350 void ThrowIOException(const char* fmt, ...) { 351 va_list args; 352 va_start(args, fmt); 353 ThrowException("Ljava/io/IOException;", nullptr, fmt, &args); 354 va_end(args); 355 } 356 357 void ThrowWrappedIOException(const char* fmt, ...) { 358 va_list args; 359 va_start(args, fmt); 360 ThrowWrappedException("Ljava/io/IOException;", nullptr, fmt, &args); 361 va_end(args); 362 } 363 364 // LinkageError 365 366 void ThrowLinkageError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) { 367 va_list args; 368 va_start(args, fmt); 369 ThrowException("Ljava/lang/LinkageError;", referrer, fmt, &args); 370 va_end(args); 371 } 372 373 void ThrowWrappedLinkageError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) { 374 va_list args; 375 va_start(args, fmt); 376 ThrowWrappedException("Ljava/lang/LinkageError;", referrer, fmt, &args); 377 va_end(args); 378 } 379 380 // NegativeArraySizeException 381 382 void ThrowNegativeArraySizeException(int size) { 383 ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr, 384 StringPrintf("%d", size).c_str()); 385 } 386 387 void ThrowNegativeArraySizeException(const char* msg) { 388 ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr, msg); 389 } 390 391 // NoSuchFieldError 392 393 void ThrowNoSuchFieldError(const StringPiece& scope, ObjPtr<mirror::Class> c, 394 const StringPiece& type, const StringPiece& name) { 395 std::ostringstream msg; 396 std::string temp; 397 msg << "No " << scope << "field " << name << " of type " << type 398 << " in class " << c->GetDescriptor(&temp) << " or its superclasses"; 399 ThrowException("Ljava/lang/NoSuchFieldError;", c, msg.str().c_str()); 400 } 401 402 void ThrowNoSuchFieldException(ObjPtr<mirror::Class> c, const StringPiece& name) { 403 std::ostringstream msg; 404 std::string temp; 405 msg << "No field " << name << " in class " << c->GetDescriptor(&temp); 406 ThrowException("Ljava/lang/NoSuchFieldException;", c, msg.str().c_str()); 407 } 408 409 // NoSuchMethodError 410 411 void ThrowNoSuchMethodError(InvokeType type, ObjPtr<mirror::Class> c, const StringPiece& name, 412 const Signature& signature) { 413 std::ostringstream msg; 414 std::string temp; 415 msg << "No " << type << " method " << name << signature 416 << " in class " << c->GetDescriptor(&temp) << " or its super classes"; 417 ThrowException("Ljava/lang/NoSuchMethodError;", c, msg.str().c_str()); 418 } 419 420 // NullPointerException 421 422 void ThrowNullPointerExceptionForFieldAccess(ArtField* field, bool is_read) { 423 std::ostringstream msg; 424 msg << "Attempt to " << (is_read ? "read from" : "write to") 425 << " field '" << ArtField::PrettyField(field, true) << "' on a null object reference"; 426 ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str()); 427 } 428 429 static void ThrowNullPointerExceptionForMethodAccessImpl(uint32_t method_idx, 430 const DexFile& dex_file, 431 InvokeType type) 432 REQUIRES_SHARED(Locks::mutator_lock_) { 433 std::ostringstream msg; 434 msg << "Attempt to invoke " << type << " method '" 435 << dex_file.PrettyMethod(method_idx, true) << "' on a null object reference"; 436 ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str()); 437 } 438 439 void ThrowNullPointerExceptionForMethodAccess(uint32_t method_idx, 440 InvokeType type) { 441 ObjPtr<mirror::DexCache> dex_cache = 442 Thread::Current()->GetCurrentMethod(nullptr)->GetDeclaringClass()->GetDexCache(); 443 const DexFile& dex_file = *dex_cache->GetDexFile(); 444 ThrowNullPointerExceptionForMethodAccessImpl(method_idx, dex_file, type); 445 } 446 447 void ThrowNullPointerExceptionForMethodAccess(ArtMethod* method, 448 InvokeType type) { 449 ObjPtr<mirror::DexCache> dex_cache = method->GetDeclaringClass()->GetDexCache(); 450 const DexFile& dex_file = *dex_cache->GetDexFile(); 451 ThrowNullPointerExceptionForMethodAccessImpl(method->GetDexMethodIndex(), 452 dex_file, type); 453 } 454 455 static bool IsValidReadBarrierImplicitCheck(uintptr_t addr) { 456 DCHECK(kEmitCompilerReadBarrier); 457 uint32_t monitor_offset = mirror::Object::MonitorOffset().Uint32Value(); 458 if (kUseBakerReadBarrier && 459 (kRuntimeISA == InstructionSet::kX86 || kRuntimeISA == InstructionSet::kX86_64)) { 460 constexpr uint32_t gray_byte_position = LockWord::kReadBarrierStateShift / kBitsPerByte; 461 monitor_offset += gray_byte_position; 462 } 463 return addr == monitor_offset; 464 } 465 466 static bool IsValidImplicitCheck(uintptr_t addr, const Instruction& instr) 467 REQUIRES_SHARED(Locks::mutator_lock_) { 468 if (!CanDoImplicitNullCheckOn(addr)) { 469 return false; 470 } 471 472 switch (instr.Opcode()) { 473 case Instruction::INVOKE_DIRECT: 474 case Instruction::INVOKE_DIRECT_RANGE: 475 case Instruction::INVOKE_VIRTUAL: 476 case Instruction::INVOKE_VIRTUAL_RANGE: 477 case Instruction::INVOKE_INTERFACE: 478 case Instruction::INVOKE_INTERFACE_RANGE: 479 case Instruction::INVOKE_POLYMORPHIC: 480 case Instruction::INVOKE_POLYMORPHIC_RANGE: 481 case Instruction::INVOKE_VIRTUAL_QUICK: 482 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { 483 // Without inlining, we could just check that the offset is the class offset. 484 // However, when inlining, the compiler can (validly) merge the null check with a field access 485 // on the same object. Note that the stack map at the NPE will reflect the invoke's location, 486 // which is the caller. 487 return true; 488 } 489 490 case Instruction::IGET_OBJECT: 491 if (kEmitCompilerReadBarrier && IsValidReadBarrierImplicitCheck(addr)) { 492 return true; 493 } 494 FALLTHROUGH_INTENDED; 495 case Instruction::IGET: 496 case Instruction::IGET_WIDE: 497 case Instruction::IGET_BOOLEAN: 498 case Instruction::IGET_BYTE: 499 case Instruction::IGET_CHAR: 500 case Instruction::IGET_SHORT: 501 case Instruction::IPUT: 502 case Instruction::IPUT_WIDE: 503 case Instruction::IPUT_OBJECT: 504 case Instruction::IPUT_BOOLEAN: 505 case Instruction::IPUT_BYTE: 506 case Instruction::IPUT_CHAR: 507 case Instruction::IPUT_SHORT: { 508 // We might be doing an implicit null check with an offset that doesn't correspond 509 // to the instruction, for example with two field accesses and the first one being 510 // eliminated or re-ordered. 511 return true; 512 } 513 514 case Instruction::IGET_OBJECT_QUICK: 515 if (kEmitCompilerReadBarrier && IsValidReadBarrierImplicitCheck(addr)) { 516 return true; 517 } 518 FALLTHROUGH_INTENDED; 519 case Instruction::IGET_QUICK: 520 case Instruction::IGET_BOOLEAN_QUICK: 521 case Instruction::IGET_BYTE_QUICK: 522 case Instruction::IGET_CHAR_QUICK: 523 case Instruction::IGET_SHORT_QUICK: 524 case Instruction::IGET_WIDE_QUICK: 525 case Instruction::IPUT_QUICK: 526 case Instruction::IPUT_BOOLEAN_QUICK: 527 case Instruction::IPUT_BYTE_QUICK: 528 case Instruction::IPUT_CHAR_QUICK: 529 case Instruction::IPUT_SHORT_QUICK: 530 case Instruction::IPUT_WIDE_QUICK: 531 case Instruction::IPUT_OBJECT_QUICK: { 532 // We might be doing an implicit null check with an offset that doesn't correspond 533 // to the instruction, for example with two field accesses and the first one being 534 // eliminated or re-ordered. 535 return true; 536 } 537 538 case Instruction::AGET_OBJECT: 539 if (kEmitCompilerReadBarrier && IsValidReadBarrierImplicitCheck(addr)) { 540 return true; 541 } 542 FALLTHROUGH_INTENDED; 543 case Instruction::AGET: 544 case Instruction::AGET_WIDE: 545 case Instruction::AGET_BOOLEAN: 546 case Instruction::AGET_BYTE: 547 case Instruction::AGET_CHAR: 548 case Instruction::AGET_SHORT: 549 case Instruction::APUT: 550 case Instruction::APUT_WIDE: 551 case Instruction::APUT_OBJECT: 552 case Instruction::APUT_BOOLEAN: 553 case Instruction::APUT_BYTE: 554 case Instruction::APUT_CHAR: 555 case Instruction::APUT_SHORT: 556 case Instruction::FILL_ARRAY_DATA: 557 case Instruction::ARRAY_LENGTH: { 558 // The length access should crash. We currently do not do implicit checks on 559 // the array access itself. 560 return (addr == 0u) || (addr == mirror::Array::LengthOffset().Uint32Value()); 561 } 562 563 default: { 564 // We have covered all the cases where an NPE could occur. 565 // Note that this must be kept in sync with the compiler, and adding 566 // any new way to do implicit checks in the compiler should also update 567 // this code. 568 return false; 569 } 570 } 571 } 572 573 void ThrowNullPointerExceptionFromDexPC(bool check_address, uintptr_t addr) { 574 uint32_t throw_dex_pc; 575 ArtMethod* method = Thread::Current()->GetCurrentMethod(&throw_dex_pc); 576 CodeItemInstructionAccessor accessor(method->DexInstructions()); 577 CHECK_LT(throw_dex_pc, accessor.InsnsSizeInCodeUnits()); 578 const Instruction& instr = accessor.InstructionAt(throw_dex_pc); 579 if (check_address && !IsValidImplicitCheck(addr, instr)) { 580 const DexFile* dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile(); 581 LOG(FATAL) << "Invalid address for an implicit NullPointerException check: " 582 << "0x" << std::hex << addr << std::dec 583 << ", at " 584 << instr.DumpString(dex_file) 585 << " in " 586 << method->PrettyMethod(); 587 } 588 589 switch (instr.Opcode()) { 590 case Instruction::INVOKE_DIRECT: 591 ThrowNullPointerExceptionForMethodAccess(instr.VRegB_35c(), kDirect); 592 break; 593 case Instruction::INVOKE_DIRECT_RANGE: 594 ThrowNullPointerExceptionForMethodAccess(instr.VRegB_3rc(), kDirect); 595 break; 596 case Instruction::INVOKE_VIRTUAL: 597 ThrowNullPointerExceptionForMethodAccess(instr.VRegB_35c(), kVirtual); 598 break; 599 case Instruction::INVOKE_VIRTUAL_RANGE: 600 ThrowNullPointerExceptionForMethodAccess(instr.VRegB_3rc(), kVirtual); 601 break; 602 case Instruction::INVOKE_INTERFACE: 603 ThrowNullPointerExceptionForMethodAccess(instr.VRegB_35c(), kInterface); 604 break; 605 case Instruction::INVOKE_INTERFACE_RANGE: 606 ThrowNullPointerExceptionForMethodAccess(instr.VRegB_3rc(), kInterface); 607 break; 608 case Instruction::INVOKE_POLYMORPHIC: 609 ThrowNullPointerExceptionForMethodAccess(instr.VRegB_45cc(), kVirtual); 610 break; 611 case Instruction::INVOKE_POLYMORPHIC_RANGE: 612 ThrowNullPointerExceptionForMethodAccess(instr.VRegB_4rcc(), kVirtual); 613 break; 614 case Instruction::INVOKE_VIRTUAL_QUICK: 615 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { 616 uint16_t method_idx = method->GetIndexFromQuickening(throw_dex_pc); 617 if (method_idx != DexFile::kDexNoIndex16) { 618 // NPE with precise message. 619 ThrowNullPointerExceptionForMethodAccess(method_idx, kVirtual); 620 } else { 621 // NPE with imprecise message. 622 ThrowNullPointerException("Attempt to invoke a virtual method on a null object reference"); 623 } 624 break; 625 } 626 case Instruction::IGET: 627 case Instruction::IGET_WIDE: 628 case Instruction::IGET_OBJECT: 629 case Instruction::IGET_BOOLEAN: 630 case Instruction::IGET_BYTE: 631 case Instruction::IGET_CHAR: 632 case Instruction::IGET_SHORT: { 633 ArtField* field = 634 Runtime::Current()->GetClassLinker()->ResolveField(instr.VRegC_22c(), method, false); 635 Thread::Current()->ClearException(); // Resolution may fail, ignore. 636 ThrowNullPointerExceptionForFieldAccess(field, true /* read */); 637 break; 638 } 639 case Instruction::IGET_QUICK: 640 case Instruction::IGET_BOOLEAN_QUICK: 641 case Instruction::IGET_BYTE_QUICK: 642 case Instruction::IGET_CHAR_QUICK: 643 case Instruction::IGET_SHORT_QUICK: 644 case Instruction::IGET_WIDE_QUICK: 645 case Instruction::IGET_OBJECT_QUICK: { 646 uint16_t field_idx = method->GetIndexFromQuickening(throw_dex_pc); 647 ArtField* field = nullptr; 648 CHECK_NE(field_idx, DexFile::kDexNoIndex16); 649 field = Runtime::Current()->GetClassLinker()->ResolveField( 650 field_idx, method, /* is_static */ false); 651 Thread::Current()->ClearException(); // Resolution may fail, ignore. 652 ThrowNullPointerExceptionForFieldAccess(field, true /* read */); 653 break; 654 } 655 case Instruction::IPUT: 656 case Instruction::IPUT_WIDE: 657 case Instruction::IPUT_OBJECT: 658 case Instruction::IPUT_BOOLEAN: 659 case Instruction::IPUT_BYTE: 660 case Instruction::IPUT_CHAR: 661 case Instruction::IPUT_SHORT: { 662 ArtField* field = Runtime::Current()->GetClassLinker()->ResolveField( 663 instr.VRegC_22c(), method, /* is_static */ false); 664 Thread::Current()->ClearException(); // Resolution may fail, ignore. 665 ThrowNullPointerExceptionForFieldAccess(field, false /* write */); 666 break; 667 } 668 case Instruction::IPUT_QUICK: 669 case Instruction::IPUT_BOOLEAN_QUICK: 670 case Instruction::IPUT_BYTE_QUICK: 671 case Instruction::IPUT_CHAR_QUICK: 672 case Instruction::IPUT_SHORT_QUICK: 673 case Instruction::IPUT_WIDE_QUICK: 674 case Instruction::IPUT_OBJECT_QUICK: { 675 uint16_t field_idx = method->GetIndexFromQuickening(throw_dex_pc); 676 ArtField* field = nullptr; 677 CHECK_NE(field_idx, DexFile::kDexNoIndex16); 678 field = Runtime::Current()->GetClassLinker()->ResolveField( 679 field_idx, method, /* is_static */ false); 680 Thread::Current()->ClearException(); // Resolution may fail, ignore. 681 ThrowNullPointerExceptionForFieldAccess(field, false /* write */); 682 break; 683 } 684 case Instruction::AGET: 685 case Instruction::AGET_WIDE: 686 case Instruction::AGET_OBJECT: 687 case Instruction::AGET_BOOLEAN: 688 case Instruction::AGET_BYTE: 689 case Instruction::AGET_CHAR: 690 case Instruction::AGET_SHORT: 691 ThrowException("Ljava/lang/NullPointerException;", nullptr, 692 "Attempt to read from null array"); 693 break; 694 case Instruction::APUT: 695 case Instruction::APUT_WIDE: 696 case Instruction::APUT_OBJECT: 697 case Instruction::APUT_BOOLEAN: 698 case Instruction::APUT_BYTE: 699 case Instruction::APUT_CHAR: 700 case Instruction::APUT_SHORT: 701 ThrowException("Ljava/lang/NullPointerException;", nullptr, 702 "Attempt to write to null array"); 703 break; 704 case Instruction::ARRAY_LENGTH: 705 ThrowException("Ljava/lang/NullPointerException;", nullptr, 706 "Attempt to get length of null array"); 707 break; 708 case Instruction::FILL_ARRAY_DATA: { 709 ThrowException("Ljava/lang/NullPointerException;", nullptr, 710 "Attempt to write to null array"); 711 break; 712 } 713 case Instruction::MONITOR_ENTER: 714 case Instruction::MONITOR_EXIT: { 715 ThrowException("Ljava/lang/NullPointerException;", nullptr, 716 "Attempt to do a synchronize operation on a null object"); 717 break; 718 } 719 default: { 720 const DexFile* dex_file = 721 method->GetDeclaringClass()->GetDexCache()->GetDexFile(); 722 LOG(FATAL) << "NullPointerException at an unexpected instruction: " 723 << instr.DumpString(dex_file) 724 << " in " 725 << method->PrettyMethod(); 726 break; 727 } 728 } 729 } 730 731 void ThrowNullPointerException(const char* msg) { 732 ThrowException("Ljava/lang/NullPointerException;", nullptr, msg); 733 } 734 735 // ReadOnlyBufferException 736 737 void ThrowReadOnlyBufferException() { 738 Thread::Current()->ThrowNewException("Ljava/nio/ReadOnlyBufferException;", nullptr); 739 } 740 741 // RuntimeException 742 743 void ThrowRuntimeException(const char* fmt, ...) { 744 va_list args; 745 va_start(args, fmt); 746 ThrowException("Ljava/lang/RuntimeException;", nullptr, fmt, &args); 747 va_end(args); 748 } 749 750 // SecurityException 751 752 void ThrowSecurityException(const char* fmt, ...) { 753 va_list args; 754 va_start(args, fmt); 755 ThrowException("Ljava/lang/SecurityException;", nullptr, fmt, &args); 756 va_end(args); 757 } 758 759 // Stack overflow. 760 761 void ThrowStackOverflowError(Thread* self) { 762 if (self->IsHandlingStackOverflow()) { 763 LOG(ERROR) << "Recursive stack overflow."; 764 // We don't fail here because SetStackEndForStackOverflow will print better diagnostics. 765 } 766 767 self->SetStackEndForStackOverflow(); // Allow space on the stack for constructor to execute. 768 JNIEnvExt* env = self->GetJniEnv(); 769 std::string msg("stack size "); 770 msg += PrettySize(self->GetStackSize()); 771 772 // Avoid running Java code for exception initialization. 773 // TODO: Checks to make this a bit less brittle. 774 775 std::string error_msg; 776 777 // Allocate an uninitialized object. 778 ScopedLocalRef<jobject> exc(env, 779 env->AllocObject(WellKnownClasses::java_lang_StackOverflowError)); 780 if (exc.get() != nullptr) { 781 // "Initialize". 782 // StackOverflowError -> VirtualMachineError -> Error -> Throwable -> Object. 783 // Only Throwable has "custom" fields: 784 // String detailMessage. 785 // Throwable cause (= this). 786 // List<Throwable> suppressedExceptions (= Collections.emptyList()). 787 // Object stackState; 788 // StackTraceElement[] stackTrace; 789 // Only Throwable has a non-empty constructor: 790 // this.stackTrace = EmptyArray.STACK_TRACE_ELEMENT; 791 // fillInStackTrace(); 792 793 // detailMessage. 794 // TODO: Use String::FromModifiedUTF...? 795 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg.c_str())); 796 if (s.get() != nullptr) { 797 env->SetObjectField(exc.get(), WellKnownClasses::java_lang_Throwable_detailMessage, s.get()); 798 799 // cause. 800 env->SetObjectField(exc.get(), WellKnownClasses::java_lang_Throwable_cause, exc.get()); 801 802 // suppressedExceptions. 803 ScopedLocalRef<jobject> emptylist(env, env->GetStaticObjectField( 804 WellKnownClasses::java_util_Collections, 805 WellKnownClasses::java_util_Collections_EMPTY_LIST)); 806 CHECK(emptylist.get() != nullptr); 807 env->SetObjectField(exc.get(), 808 WellKnownClasses::java_lang_Throwable_suppressedExceptions, 809 emptylist.get()); 810 811 // stackState is set as result of fillInStackTrace. fillInStackTrace calls 812 // nativeFillInStackTrace. 813 ScopedLocalRef<jobject> stack_state_val(env, nullptr); 814 { 815 ScopedObjectAccessUnchecked soa(env); 816 stack_state_val.reset(soa.Self()->CreateInternalStackTrace<false>(soa)); 817 } 818 if (stack_state_val.get() != nullptr) { 819 env->SetObjectField(exc.get(), 820 WellKnownClasses::java_lang_Throwable_stackState, 821 stack_state_val.get()); 822 823 // stackTrace. 824 ScopedLocalRef<jobject> stack_trace_elem(env, env->GetStaticObjectField( 825 WellKnownClasses::libcore_util_EmptyArray, 826 WellKnownClasses::libcore_util_EmptyArray_STACK_TRACE_ELEMENT)); 827 env->SetObjectField(exc.get(), 828 WellKnownClasses::java_lang_Throwable_stackTrace, 829 stack_trace_elem.get()); 830 } else { 831 error_msg = "Could not create stack trace."; 832 } 833 // Throw the exception. 834 self->SetException(self->DecodeJObject(exc.get())->AsThrowable()); 835 } else { 836 // Could not allocate a string object. 837 error_msg = "Couldn't throw new StackOverflowError because JNI NewStringUTF failed."; 838 } 839 } else { 840 error_msg = "Could not allocate StackOverflowError object."; 841 } 842 843 if (!error_msg.empty()) { 844 LOG(WARNING) << error_msg; 845 CHECK(self->IsExceptionPending()); 846 } 847 848 bool explicit_overflow_check = Runtime::Current()->ExplicitStackOverflowChecks(); 849 self->ResetDefaultStackEnd(); // Return to default stack size. 850 851 // And restore protection if implicit checks are on. 852 if (!explicit_overflow_check) { 853 self->ProtectStack(); 854 } 855 } 856 857 // StringIndexOutOfBoundsException 858 859 void ThrowStringIndexOutOfBoundsException(int index, int length) { 860 ThrowException("Ljava/lang/StringIndexOutOfBoundsException;", nullptr, 861 StringPrintf("length=%d; index=%d", length, index).c_str()); 862 } 863 864 // UnsupportedOperationException 865 866 void ThrowUnsupportedOperationException() { 867 ThrowException("Ljava/lang/UnsupportedOperationException;"); 868 } 869 870 // VerifyError 871 872 void ThrowVerifyError(ObjPtr<mirror::Class> referrer, const char* fmt, ...) { 873 va_list args; 874 va_start(args, fmt); 875 ThrowException("Ljava/lang/VerifyError;", referrer, fmt, &args); 876 va_end(args); 877 } 878 879 // WrongMethodTypeException 880 881 void ThrowWrongMethodTypeException(mirror::MethodType* expected_type, 882 mirror::MethodType* actual_type) { 883 ThrowException("Ljava/lang/invoke/WrongMethodTypeException;", 884 nullptr, 885 StringPrintf("Expected %s but was %s", 886 expected_type->PrettyDescriptor().c_str(), 887 actual_type->PrettyDescriptor().c_str()).c_str()); 888 } 889 890 } // namespace art 891