events.cc revision 0a5ec3dde72d93111a1cfe229e4f1888f06a9541
1/* Copyright (C) 2016 The Android Open Source Project 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This file implements interfaces from the file jvmti.h. This implementation 5 * is licensed under the same terms as the file jvmti.h. The 6 * copyright and license information for the file jvmti.h follows. 7 * 8 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10 * 11 * This code is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License version 2 only, as 13 * published by the Free Software Foundation. Oracle designates this 14 * particular file as subject to the "Classpath" exception as provided 15 * by Oracle in the LICENSE file that accompanied this code. 16 * 17 * This code is distributed in the hope that it will be useful, but WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 * version 2 for more details (a copy is included in the LICENSE file that 21 * accompanied this code). 22 * 23 * You should have received a copy of the GNU General Public License version 24 * 2 along with this work; if not, write to the Free Software Foundation, 25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26 * 27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28 * or visit www.oracle.com if you need additional information or have any 29 * questions. 30 */ 31 32#include "events-inl.h" 33 34#include "art_field-inl.h" 35#include "art_jvmti.h" 36#include "art_method-inl.h" 37#include "base/logging.h" 38#include "gc/allocation_listener.h" 39#include "gc/gc_pause_listener.h" 40#include "gc/heap.h" 41#include "gc/scoped_gc_critical_section.h" 42#include "handle_scope-inl.h" 43#include "instrumentation.h" 44#include "jni_env_ext-inl.h" 45#include "jni_internal.h" 46#include "mirror/class.h" 47#include "mirror/object-inl.h" 48#include "nativehelper/ScopedLocalRef.h" 49#include "runtime.h" 50#include "scoped_thread_state_change-inl.h" 51#include "stack.h" 52#include "thread-inl.h" 53#include "thread_list.h" 54#include "ti_phase.h" 55 56namespace openjdkjvmti { 57 58bool EventMasks::IsEnabledAnywhere(ArtJvmtiEvent event) { 59 return global_event_mask.Test(event) || unioned_thread_event_mask.Test(event); 60} 61 62EventMask& EventMasks::GetEventMask(art::Thread* thread) { 63 if (thread == nullptr) { 64 return global_event_mask; 65 } 66 67 for (auto& pair : thread_event_masks) { 68 const UniqueThread& unique_thread = pair.first; 69 if (unique_thread.first == thread && 70 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) { 71 return pair.second; 72 } 73 } 74 75 // TODO: Remove old UniqueThread with the same pointer, if exists. 76 77 thread_event_masks.emplace_back(UniqueThread(thread, thread->GetTid()), EventMask()); 78 return thread_event_masks.back().second; 79} 80 81EventMask* EventMasks::GetEventMaskOrNull(art::Thread* thread) { 82 if (thread == nullptr) { 83 return &global_event_mask; 84 } 85 86 for (auto& pair : thread_event_masks) { 87 const UniqueThread& unique_thread = pair.first; 88 if (unique_thread.first == thread && 89 unique_thread.second == static_cast<uint32_t>(thread->GetTid())) { 90 return &pair.second; 91 } 92 } 93 94 return nullptr; 95} 96 97 98void EventMasks::EnableEvent(art::Thread* thread, ArtJvmtiEvent event) { 99 DCHECK(EventMask::EventIsInRange(event)); 100 GetEventMask(thread).Set(event); 101 if (thread != nullptr) { 102 unioned_thread_event_mask.Set(event, true); 103 } 104} 105 106void EventMasks::DisableEvent(art::Thread* thread, ArtJvmtiEvent event) { 107 DCHECK(EventMask::EventIsInRange(event)); 108 GetEventMask(thread).Set(event, false); 109 if (thread != nullptr) { 110 // Regenerate union for the event. 111 bool union_value = false; 112 for (auto& pair : thread_event_masks) { 113 union_value |= pair.second.Test(event); 114 if (union_value) { 115 break; 116 } 117 } 118 unioned_thread_event_mask.Set(event, union_value); 119 } 120} 121 122void EventMasks::HandleChangedCapabilities(const jvmtiCapabilities& caps, bool caps_added) { 123 if (UNLIKELY(caps.can_retransform_classes == 1)) { 124 // If we are giving this env the retransform classes cap we need to switch all events of 125 // NonTransformable to Transformable and vice versa. 126 ArtJvmtiEvent to_remove = caps_added ? ArtJvmtiEvent::kClassFileLoadHookNonRetransformable 127 : ArtJvmtiEvent::kClassFileLoadHookRetransformable; 128 ArtJvmtiEvent to_add = caps_added ? ArtJvmtiEvent::kClassFileLoadHookRetransformable 129 : ArtJvmtiEvent::kClassFileLoadHookNonRetransformable; 130 if (global_event_mask.Test(to_remove)) { 131 CHECK(!global_event_mask.Test(to_add)); 132 global_event_mask.Set(to_remove, false); 133 global_event_mask.Set(to_add, true); 134 } 135 136 if (unioned_thread_event_mask.Test(to_remove)) { 137 CHECK(!unioned_thread_event_mask.Test(to_add)); 138 unioned_thread_event_mask.Set(to_remove, false); 139 unioned_thread_event_mask.Set(to_add, true); 140 } 141 for (auto thread_mask : thread_event_masks) { 142 if (thread_mask.second.Test(to_remove)) { 143 CHECK(!thread_mask.second.Test(to_add)); 144 thread_mask.second.Set(to_remove, false); 145 thread_mask.second.Set(to_add, true); 146 } 147 } 148 } 149} 150 151void EventHandler::RegisterArtJvmTiEnv(ArtJvmTiEnv* env) { 152 // Since we never shrink this array we might as well try to fill gaps. 153 auto it = std::find(envs.begin(), envs.end(), nullptr); 154 if (it != envs.end()) { 155 *it = env; 156 } else { 157 envs.push_back(env); 158 } 159} 160 161void EventHandler::RemoveArtJvmTiEnv(ArtJvmTiEnv* env) { 162 // Since we might be currently iterating over the envs list we cannot actually erase elements. 163 // Instead we will simply replace them with 'nullptr' and skip them manually. 164 auto it = std::find(envs.begin(), envs.end(), env); 165 if (it != envs.end()) { 166 *it = nullptr; 167 for (size_t i = static_cast<size_t>(ArtJvmtiEvent::kMinEventTypeVal); 168 i <= static_cast<size_t>(ArtJvmtiEvent::kMaxEventTypeVal); 169 ++i) { 170 RecalculateGlobalEventMask(static_cast<ArtJvmtiEvent>(i)); 171 } 172 } 173} 174 175static bool IsThreadControllable(ArtJvmtiEvent event) { 176 switch (event) { 177 case ArtJvmtiEvent::kVmInit: 178 case ArtJvmtiEvent::kVmStart: 179 case ArtJvmtiEvent::kVmDeath: 180 case ArtJvmtiEvent::kThreadStart: 181 case ArtJvmtiEvent::kCompiledMethodLoad: 182 case ArtJvmtiEvent::kCompiledMethodUnload: 183 case ArtJvmtiEvent::kDynamicCodeGenerated: 184 case ArtJvmtiEvent::kDataDumpRequest: 185 return false; 186 187 default: 188 return true; 189 } 190} 191 192class JvmtiAllocationListener : public art::gc::AllocationListener { 193 public: 194 explicit JvmtiAllocationListener(EventHandler* handler) : handler_(handler) {} 195 196 void ObjectAllocated(art::Thread* self, art::ObjPtr<art::mirror::Object>* obj, size_t byte_count) 197 OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 198 DCHECK_EQ(self, art::Thread::Current()); 199 200 if (handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kVmObjectAlloc)) { 201 art::StackHandleScope<1> hs(self); 202 auto h = hs.NewHandleWrapper(obj); 203 // jvmtiEventVMObjectAlloc parameters: 204 // jvmtiEnv *jvmti_env, 205 // JNIEnv* jni_env, 206 // jthread thread, 207 // jobject object, 208 // jclass object_klass, 209 // jlong size 210 art::JNIEnvExt* jni_env = self->GetJniEnv(); 211 212 jthread thread_peer; 213 if (self->IsStillStarting()) { 214 thread_peer = nullptr; 215 } else { 216 thread_peer = jni_env->AddLocalReference<jthread>(self->GetPeer()); 217 } 218 219 ScopedLocalRef<jthread> thread(jni_env, thread_peer); 220 ScopedLocalRef<jobject> object( 221 jni_env, jni_env->AddLocalReference<jobject>(*obj)); 222 ScopedLocalRef<jclass> klass( 223 jni_env, jni_env->AddLocalReference<jclass>(obj->Ptr()->GetClass())); 224 225 handler_->DispatchEvent<ArtJvmtiEvent::kVmObjectAlloc>(self, 226 reinterpret_cast<JNIEnv*>(jni_env), 227 thread.get(), 228 object.get(), 229 klass.get(), 230 static_cast<jlong>(byte_count)); 231 } 232 } 233 234 private: 235 EventHandler* handler_; 236}; 237 238static void SetupObjectAllocationTracking(art::gc::AllocationListener* listener, bool enable) { 239 // We must not hold the mutator lock here, but if we're in FastJNI, for example, we might. For 240 // now, do a workaround: (possibly) acquire and release. 241 art::ScopedObjectAccess soa(art::Thread::Current()); 242 art::ScopedThreadSuspension sts(soa.Self(), art::ThreadState::kSuspended); 243 if (enable) { 244 art::Runtime::Current()->GetHeap()->SetAllocationListener(listener); 245 } else { 246 art::Runtime::Current()->GetHeap()->RemoveAllocationListener(); 247 } 248} 249 250// Report GC pauses (see spec) as GARBAGE_COLLECTION_START and GARBAGE_COLLECTION_END. 251class JvmtiGcPauseListener : public art::gc::GcPauseListener { 252 public: 253 explicit JvmtiGcPauseListener(EventHandler* handler) 254 : handler_(handler), 255 start_enabled_(false), 256 finish_enabled_(false) {} 257 258 void StartPause() OVERRIDE { 259 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionStart>(nullptr); 260 } 261 262 void EndPause() OVERRIDE { 263 handler_->DispatchEvent<ArtJvmtiEvent::kGarbageCollectionFinish>(nullptr); 264 } 265 266 bool IsEnabled() { 267 return start_enabled_ || finish_enabled_; 268 } 269 270 void SetStartEnabled(bool e) { 271 start_enabled_ = e; 272 } 273 274 void SetFinishEnabled(bool e) { 275 finish_enabled_ = e; 276 } 277 278 private: 279 EventHandler* handler_; 280 bool start_enabled_; 281 bool finish_enabled_; 282}; 283 284static void SetupGcPauseTracking(JvmtiGcPauseListener* listener, ArtJvmtiEvent event, bool enable) { 285 bool old_state = listener->IsEnabled(); 286 287 if (event == ArtJvmtiEvent::kGarbageCollectionStart) { 288 listener->SetStartEnabled(enable); 289 } else { 290 listener->SetFinishEnabled(enable); 291 } 292 293 bool new_state = listener->IsEnabled(); 294 295 if (old_state != new_state) { 296 if (new_state) { 297 art::Runtime::Current()->GetHeap()->SetGcPauseListener(listener); 298 } else { 299 art::Runtime::Current()->GetHeap()->RemoveGcPauseListener(); 300 } 301 } 302} 303 304template<typename Type> 305static Type AddLocalRef(art::JNIEnvExt* e, art::mirror::Object* obj) 306 REQUIRES_SHARED(art::Locks::mutator_lock_) { 307 return (obj == nullptr) ? nullptr : e->AddLocalReference<Type>(obj); 308} 309 310class JvmtiMethodTraceListener FINAL : public art::instrumentation::InstrumentationListener { 311 public: 312 explicit JvmtiMethodTraceListener(EventHandler* handler) : event_handler_(handler) {} 313 314 template<ArtJvmtiEvent kEvent, typename ...Args> 315 void RunEventCallback(art::Thread* self, art::JNIEnvExt* jnienv, Args... args) 316 REQUIRES_SHARED(art::Locks::mutator_lock_) { 317 ScopedLocalRef<jthread> thread_jni(jnienv, AddLocalRef<jthread>(jnienv, self->GetPeer())); 318 // Just give the event a good sized JNI frame. 100 should be fine. 319 jnienv->PushFrame(100); 320 { 321 // Need to do trampoline! :( 322 art::ScopedThreadSuspension sts(self, art::ThreadState::kNative); 323 event_handler_->DispatchEvent<kEvent>(self, 324 static_cast<JNIEnv*>(jnienv), 325 thread_jni.get(), 326 args...); 327 } 328 jnienv->PopFrame(); 329 } 330 331 // Call-back for when a method is entered. 332 void MethodEntered(art::Thread* self, 333 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 334 art::ArtMethod* method, 335 uint32_t dex_pc ATTRIBUTE_UNUSED) 336 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 337 if (!method->IsRuntimeMethod() && 338 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodEntry)) { 339 art::JNIEnvExt* jnienv = self->GetJniEnv(); 340 RunEventCallback<ArtJvmtiEvent::kMethodEntry>(self, 341 jnienv, 342 art::jni::EncodeArtMethod(method)); 343 } 344 } 345 346 // Callback for when a method is exited with a reference return value. 347 void MethodExited(art::Thread* self, 348 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 349 art::ArtMethod* method, 350 uint32_t dex_pc ATTRIBUTE_UNUSED, 351 art::Handle<art::mirror::Object> return_value) 352 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 353 if (!method->IsRuntimeMethod() && 354 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 355 DCHECK_EQ(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot) 356 << method->PrettyMethod(); 357 DCHECK(!self->IsExceptionPending()); 358 jvalue val; 359 art::JNIEnvExt* jnienv = self->GetJniEnv(); 360 ScopedLocalRef<jobject> return_jobj(jnienv, AddLocalRef<jobject>(jnienv, return_value.Get())); 361 val.l = return_jobj.get(); 362 RunEventCallback<ArtJvmtiEvent::kMethodExit>( 363 self, 364 jnienv, 365 art::jni::EncodeArtMethod(method), 366 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE), 367 val); 368 } 369 } 370 371 // Call-back for when a method is exited. 372 void MethodExited(art::Thread* self, 373 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 374 art::ArtMethod* method, 375 uint32_t dex_pc ATTRIBUTE_UNUSED, 376 const art::JValue& return_value) 377 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 378 if (!method->IsRuntimeMethod() && 379 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 380 DCHECK_NE(method->GetReturnTypePrimitive(), art::Primitive::kPrimNot) 381 << method->PrettyMethod(); 382 DCHECK(!self->IsExceptionPending()); 383 jvalue val; 384 art::JNIEnvExt* jnienv = self->GetJniEnv(); 385 // 64bit integer is the largest value in the union so we should be fine simply copying it into 386 // the union. 387 val.j = return_value.GetJ(); 388 RunEventCallback<ArtJvmtiEvent::kMethodExit>( 389 self, 390 jnienv, 391 art::jni::EncodeArtMethod(method), 392 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE), 393 val); 394 } 395 } 396 397 // Call-back for when a method is popped due to an exception throw. A method will either cause a 398 // MethodExited call-back or a MethodUnwind call-back when its activation is removed. 399 void MethodUnwind(art::Thread* self, 400 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 401 art::ArtMethod* method, 402 uint32_t dex_pc ATTRIBUTE_UNUSED) 403 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 404 if (!method->IsRuntimeMethod() && 405 event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kMethodExit)) { 406 jvalue val; 407 // Just set this to 0xffffffffffffffff so it's not uninitialized. 408 val.j = static_cast<jlong>(-1); 409 art::JNIEnvExt* jnienv = self->GetJniEnv(); 410 art::StackHandleScope<1> hs(self); 411 art::Handle<art::mirror::Throwable> old_exception(hs.NewHandle(self->GetException())); 412 CHECK(!old_exception.IsNull()); 413 self->ClearException(); 414 RunEventCallback<ArtJvmtiEvent::kMethodExit>( 415 self, 416 jnienv, 417 art::jni::EncodeArtMethod(method), 418 /*was_popped_by_exception*/ static_cast<jboolean>(JNI_TRUE), 419 val); 420 // Match RI behavior of just throwing away original exception if a new one is thrown. 421 if (LIKELY(!self->IsExceptionPending())) { 422 self->SetException(old_exception.Get()); 423 } 424 } 425 } 426 427 // Call-back for when the dex pc moves in a method. 428 void DexPcMoved(art::Thread* self, 429 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 430 art::ArtMethod* method, 431 uint32_t new_dex_pc) 432 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 433 DCHECK(!method->IsRuntimeMethod()); 434 // Default methods might be copied to multiple classes. We need to get the canonical version of 435 // this method so that we can check for breakpoints correctly. 436 // TODO We should maybe do this on other events to ensure that we are consistent WRT default 437 // methods. This could interact with obsolete methods if we ever let interface redefinition 438 // happen though. 439 method = method->GetCanonicalMethod(); 440 art::JNIEnvExt* jnienv = self->GetJniEnv(); 441 jmethodID jmethod = art::jni::EncodeArtMethod(method); 442 jlocation location = static_cast<jlocation>(new_dex_pc); 443 // Step event is reported first according to the spec. 444 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kSingleStep)) { 445 RunEventCallback<ArtJvmtiEvent::kSingleStep>(self, jnienv, jmethod, location); 446 } 447 // Next we do the Breakpoint events. The Dispatch code will filter the individual 448 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kBreakpoint)) { 449 RunEventCallback<ArtJvmtiEvent::kBreakpoint>(self, jnienv, jmethod, location); 450 } 451 } 452 453 // Call-back for when we read from a field. 454 void FieldRead(art::Thread* self, 455 art::Handle<art::mirror::Object> this_object, 456 art::ArtMethod* method, 457 uint32_t dex_pc, 458 art::ArtField* field) 459 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 460 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldAccess)) { 461 art::JNIEnvExt* jnienv = self->GetJniEnv(); 462 // DCHECK(!self->IsExceptionPending()); 463 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 464 ScopedLocalRef<jobject> fklass(jnienv, 465 AddLocalRef<jobject>(jnienv, 466 field->GetDeclaringClass().Ptr())); 467 RunEventCallback<ArtJvmtiEvent::kFieldAccess>(self, 468 jnienv, 469 art::jni::EncodeArtMethod(method), 470 static_cast<jlocation>(dex_pc), 471 static_cast<jclass>(fklass.get()), 472 this_ref.get(), 473 art::jni::EncodeArtField(field)); 474 } 475 } 476 477 void FieldWritten(art::Thread* self, 478 art::Handle<art::mirror::Object> this_object, 479 art::ArtMethod* method, 480 uint32_t dex_pc, 481 art::ArtField* field, 482 art::Handle<art::mirror::Object> new_val) 483 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 484 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) { 485 art::JNIEnvExt* jnienv = self->GetJniEnv(); 486 // DCHECK(!self->IsExceptionPending()); 487 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 488 ScopedLocalRef<jobject> fklass(jnienv, 489 AddLocalRef<jobject>(jnienv, 490 field->GetDeclaringClass().Ptr())); 491 ScopedLocalRef<jobject> fval(jnienv, AddLocalRef<jobject>(jnienv, new_val.Get())); 492 jvalue val; 493 val.l = fval.get(); 494 RunEventCallback<ArtJvmtiEvent::kFieldModification>( 495 self, 496 jnienv, 497 art::jni::EncodeArtMethod(method), 498 static_cast<jlocation>(dex_pc), 499 static_cast<jclass>(fklass.get()), 500 field->IsStatic() ? nullptr : this_ref.get(), 501 art::jni::EncodeArtField(field), 502 'L', // type_char 503 val); 504 } 505 } 506 507 // Call-back for when we write into a field. 508 void FieldWritten(art::Thread* self, 509 art::Handle<art::mirror::Object> this_object, 510 art::ArtMethod* method, 511 uint32_t dex_pc, 512 art::ArtField* field, 513 const art::JValue& field_value) 514 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 515 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFieldModification)) { 516 art::JNIEnvExt* jnienv = self->GetJniEnv(); 517 DCHECK(!self->IsExceptionPending()); 518 ScopedLocalRef<jobject> this_ref(jnienv, AddLocalRef<jobject>(jnienv, this_object.Get())); 519 ScopedLocalRef<jobject> fklass(jnienv, 520 AddLocalRef<jobject>(jnienv, 521 field->GetDeclaringClass().Ptr())); 522 char type_char = art::Primitive::Descriptor(field->GetTypeAsPrimitiveType())[0]; 523 jvalue val; 524 // 64bit integer is the largest value in the union so we should be fine simply copying it into 525 // the union. 526 val.j = field_value.GetJ(); 527 RunEventCallback<ArtJvmtiEvent::kFieldModification>( 528 self, 529 jnienv, 530 art::jni::EncodeArtMethod(method), 531 static_cast<jlocation>(dex_pc), 532 static_cast<jclass>(fklass.get()), 533 field->IsStatic() ? nullptr : this_ref.get(), // nb static field modification get given 534 // the class as this_object for some 535 // reason. 536 art::jni::EncodeArtField(field), 537 type_char, 538 val); 539 } 540 } 541 542 void WatchedFramePop(art::Thread* self, const art::ShadowFrame& frame) 543 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 544 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kFramePop)) { 545 art::JNIEnvExt* jnienv = self->GetJniEnv(); 546 jboolean is_exception_pending = self->IsExceptionPending(); 547 RunEventCallback<ArtJvmtiEvent::kFramePop>( 548 self, 549 jnienv, 550 art::jni::EncodeArtMethod(frame.GetMethod()), 551 is_exception_pending, 552 &frame); 553 } 554 } 555 556 static void FindCatchMethodsFromThrow(art::Thread* self, 557 art::Handle<art::mirror::Throwable> exception, 558 /*out*/ art::ArtMethod** out_method, 559 /*out*/ uint32_t* dex_pc) 560 REQUIRES_SHARED(art::Locks::mutator_lock_) { 561 // Finds the location where this exception will most likely be caught. We ignore intervening 562 // native frames (which could catch the exception) and return the closest java frame with a 563 // compatible catch statement. 564 class CatchLocationFinder FINAL : public art::StackVisitor { 565 public: 566 CatchLocationFinder(art::Thread* target, 567 art::Handle<art::mirror::Class> exception_class, 568 art::Context* context, 569 /*out*/ art::ArtMethod** out_catch_method, 570 /*out*/ uint32_t* out_catch_pc) 571 REQUIRES_SHARED(art::Locks::mutator_lock_) 572 : StackVisitor(target, context, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames), 573 exception_class_(exception_class), 574 catch_method_ptr_(out_catch_method), 575 catch_dex_pc_ptr_(out_catch_pc) {} 576 577 bool VisitFrame() OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 578 art::ArtMethod* method = GetMethod(); 579 DCHECK(method != nullptr); 580 if (method->IsRuntimeMethod()) { 581 return true; 582 } 583 584 if (!method->IsNative()) { 585 uint32_t cur_dex_pc = GetDexPc(); 586 if (cur_dex_pc == art::DexFile::kDexNoIndex) { 587 // This frame looks opaque. Just keep on going. 588 return true; 589 } 590 bool has_no_move_exception = false; 591 uint32_t found_dex_pc = method->FindCatchBlock( 592 exception_class_, cur_dex_pc, &has_no_move_exception); 593 if (found_dex_pc != art::DexFile::kDexNoIndex) { 594 // We found the catch. Store the result and return. 595 *catch_method_ptr_ = method; 596 *catch_dex_pc_ptr_ = found_dex_pc; 597 return false; 598 } 599 } 600 return true; 601 } 602 603 private: 604 art::Handle<art::mirror::Class> exception_class_; 605 art::ArtMethod** catch_method_ptr_; 606 uint32_t* catch_dex_pc_ptr_; 607 608 DISALLOW_COPY_AND_ASSIGN(CatchLocationFinder); 609 }; 610 611 art::StackHandleScope<1> hs(self); 612 *out_method = nullptr; 613 *dex_pc = 0; 614 std::unique_ptr<art::Context> context(art::Context::Create()); 615 616 CatchLocationFinder clf(self, 617 hs.NewHandle(exception->GetClass()), 618 context.get(), 619 /*out*/ out_method, 620 /*out*/ dex_pc); 621 clf.WalkStack(/* include_transitions */ false); 622 } 623 624 // Call-back when an exception is thrown. 625 void ExceptionThrown(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object) 626 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 627 DCHECK(self->IsExceptionThrownByCurrentMethod(exception_object.Get())); 628 // The instrumentation events get rid of this for us. 629 DCHECK(!self->IsExceptionPending()); 630 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kException)) { 631 art::JNIEnvExt* jnienv = self->GetJniEnv(); 632 art::ArtMethod* catch_method; 633 uint32_t catch_pc; 634 FindCatchMethodsFromThrow(self, exception_object, &catch_method, &catch_pc); 635 uint32_t dex_pc = 0; 636 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc, 637 /* check_suspended */ true, 638 /* abort_on_error */ art::kIsDebugBuild); 639 ScopedLocalRef<jobject> exception(jnienv, 640 AddLocalRef<jobject>(jnienv, exception_object.Get())); 641 RunEventCallback<ArtJvmtiEvent::kException>( 642 self, 643 jnienv, 644 art::jni::EncodeArtMethod(method), 645 static_cast<jlocation>(dex_pc), 646 exception.get(), 647 art::jni::EncodeArtMethod(catch_method), 648 static_cast<jlocation>(catch_pc)); 649 } 650 return; 651 } 652 653 // Call-back when an exception is handled. 654 void ExceptionHandled(art::Thread* self, art::Handle<art::mirror::Throwable> exception_object) 655 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 656 // Since the exception has already been handled there shouldn't be one pending. 657 DCHECK(!self->IsExceptionPending()); 658 if (event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kExceptionCatch)) { 659 art::JNIEnvExt* jnienv = self->GetJniEnv(); 660 uint32_t dex_pc; 661 art::ArtMethod* method = self->GetCurrentMethod(&dex_pc, 662 /* check_suspended */ true, 663 /* abort_on_error */ art::kIsDebugBuild); 664 ScopedLocalRef<jobject> exception(jnienv, 665 AddLocalRef<jobject>(jnienv, exception_object.Get())); 666 RunEventCallback<ArtJvmtiEvent::kExceptionCatch>( 667 self, 668 jnienv, 669 art::jni::EncodeArtMethod(method), 670 static_cast<jlocation>(dex_pc), 671 exception.get()); 672 } 673 return; 674 } 675 676 // Call-back for when we execute a branch. 677 void Branch(art::Thread* self ATTRIBUTE_UNUSED, 678 art::ArtMethod* method ATTRIBUTE_UNUSED, 679 uint32_t dex_pc ATTRIBUTE_UNUSED, 680 int32_t dex_pc_offset ATTRIBUTE_UNUSED) 681 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 682 return; 683 } 684 685 // Call-back for when we get an invokevirtual or an invokeinterface. 686 void InvokeVirtualOrInterface(art::Thread* self ATTRIBUTE_UNUSED, 687 art::Handle<art::mirror::Object> this_object ATTRIBUTE_UNUSED, 688 art::ArtMethod* caller ATTRIBUTE_UNUSED, 689 uint32_t dex_pc ATTRIBUTE_UNUSED, 690 art::ArtMethod* callee ATTRIBUTE_UNUSED) 691 REQUIRES_SHARED(art::Locks::mutator_lock_) OVERRIDE { 692 return; 693 } 694 695 private: 696 EventHandler* const event_handler_; 697}; 698 699static uint32_t GetInstrumentationEventsFor(ArtJvmtiEvent event) { 700 switch (event) { 701 case ArtJvmtiEvent::kMethodEntry: 702 return art::instrumentation::Instrumentation::kMethodEntered; 703 case ArtJvmtiEvent::kMethodExit: 704 return art::instrumentation::Instrumentation::kMethodExited | 705 art::instrumentation::Instrumentation::kMethodUnwind; 706 case ArtJvmtiEvent::kFieldModification: 707 return art::instrumentation::Instrumentation::kFieldWritten; 708 case ArtJvmtiEvent::kFieldAccess: 709 return art::instrumentation::Instrumentation::kFieldRead; 710 case ArtJvmtiEvent::kBreakpoint: 711 case ArtJvmtiEvent::kSingleStep: 712 return art::instrumentation::Instrumentation::kDexPcMoved; 713 case ArtJvmtiEvent::kFramePop: 714 return art::instrumentation::Instrumentation::kWatchedFramePop; 715 case ArtJvmtiEvent::kException: 716 return art::instrumentation::Instrumentation::kExceptionThrown; 717 case ArtJvmtiEvent::kExceptionCatch: 718 return art::instrumentation::Instrumentation::kExceptionHandled; 719 default: 720 LOG(FATAL) << "Unknown event "; 721 return 0; 722 } 723} 724 725static void SetupTraceListener(JvmtiMethodTraceListener* listener, 726 ArtJvmtiEvent event, 727 bool enable) { 728 art::ScopedThreadStateChange stsc(art::Thread::Current(), art::ThreadState::kNative); 729 uint32_t new_events = GetInstrumentationEventsFor(event); 730 art::instrumentation::Instrumentation* instr = art::Runtime::Current()->GetInstrumentation(); 731 art::gc::ScopedGCCriticalSection gcs(art::Thread::Current(), 732 art::gc::kGcCauseInstrumentation, 733 art::gc::kCollectorTypeInstrumentation); 734 art::ScopedSuspendAll ssa("jvmti method tracing installation"); 735 if (enable) { 736 // TODO Depending on the features being used we should be able to avoid deoptimizing everything 737 // like we do here. 738 if (!instr->AreAllMethodsDeoptimized()) { 739 instr->EnableMethodTracing("jvmti-tracing", /*needs_interpreter*/true); 740 } 741 instr->AddListener(listener, new_events); 742 } else { 743 instr->RemoveListener(listener, new_events); 744 } 745} 746 747// Makes sure that all compiled methods are AsyncDeoptimizable so we can deoptimize (and force to 748// the switch interpreter) when we try to get or set a local variable. 749void EventHandler::HandleLocalAccessCapabilityAdded() { 750 class UpdateEntryPointsClassVisitor : public art::ClassVisitor { 751 public: 752 explicit UpdateEntryPointsClassVisitor(art::Runtime* runtime) 753 : runtime_(runtime) {} 754 755 bool operator()(art::ObjPtr<art::mirror::Class> klass) 756 OVERRIDE REQUIRES(art::Locks::mutator_lock_) { 757 for (auto& m : klass->GetMethods(art::kRuntimePointerSize)) { 758 const void* code = m.GetEntryPointFromQuickCompiledCode(); 759 if (m.IsNative() || m.IsProxyMethod()) { 760 continue; 761 } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) && 762 !runtime_->IsAsyncDeoptimizeable(reinterpret_cast<uintptr_t>(code))) { 763 runtime_->GetInstrumentation()->UpdateMethodsCodeToInterpreterEntryPoint(&m); 764 } 765 } 766 return true; 767 } 768 769 private: 770 art::Runtime* runtime_; 771 }; 772 art::ScopedObjectAccess soa(art::Thread::Current()); 773 UpdateEntryPointsClassVisitor visitor(art::Runtime::Current()); 774 art::Runtime::Current()->GetClassLinker()->VisitClasses(&visitor); 775} 776 777// Handle special work for the given event type, if necessary. 778void EventHandler::HandleEventType(ArtJvmtiEvent event, bool enable) { 779 switch (event) { 780 case ArtJvmtiEvent::kVmObjectAlloc: 781 SetupObjectAllocationTracking(alloc_listener_.get(), enable); 782 return; 783 784 case ArtJvmtiEvent::kGarbageCollectionStart: 785 case ArtJvmtiEvent::kGarbageCollectionFinish: 786 SetupGcPauseTracking(gc_pause_listener_.get(), event, enable); 787 return; 788 789 case ArtJvmtiEvent::kBreakpoint: 790 case ArtJvmtiEvent::kSingleStep: { 791 ArtJvmtiEvent other = (event == ArtJvmtiEvent::kBreakpoint) ? ArtJvmtiEvent::kSingleStep 792 : ArtJvmtiEvent::kBreakpoint; 793 // We only need to do anything if there isn't already a listener installed/held-on by the 794 // other jvmti event that uses DexPcMoved. 795 if (!IsEventEnabledAnywhere(other)) { 796 SetupTraceListener(method_trace_listener_.get(), event, enable); 797 } 798 return; 799 } 800 // FramePop can never be disabled once it's been turned on since we would either need to deal 801 // with dangling pointers or have missed events. 802 case ArtJvmtiEvent::kFramePop: 803 if (!enable || (enable && frame_pop_enabled)) { 804 break; 805 } else { 806 SetupTraceListener(method_trace_listener_.get(), event, enable); 807 break; 808 } 809 case ArtJvmtiEvent::kMethodEntry: 810 case ArtJvmtiEvent::kMethodExit: 811 case ArtJvmtiEvent::kFieldAccess: 812 case ArtJvmtiEvent::kFieldModification: 813 case ArtJvmtiEvent::kException: 814 case ArtJvmtiEvent::kExceptionCatch: 815 SetupTraceListener(method_trace_listener_.get(), event, enable); 816 return; 817 818 default: 819 break; 820 } 821} 822 823// Checks to see if the env has the capabilities associated with the given event. 824static bool HasAssociatedCapability(ArtJvmTiEnv* env, 825 ArtJvmtiEvent event) { 826 jvmtiCapabilities caps = env->capabilities; 827 switch (event) { 828 case ArtJvmtiEvent::kBreakpoint: 829 return caps.can_generate_breakpoint_events == 1; 830 831 case ArtJvmtiEvent::kCompiledMethodLoad: 832 case ArtJvmtiEvent::kCompiledMethodUnload: 833 return caps.can_generate_compiled_method_load_events == 1; 834 835 case ArtJvmtiEvent::kException: 836 case ArtJvmtiEvent::kExceptionCatch: 837 return caps.can_generate_exception_events == 1; 838 839 case ArtJvmtiEvent::kFieldAccess: 840 return caps.can_generate_field_access_events == 1; 841 842 case ArtJvmtiEvent::kFieldModification: 843 return caps.can_generate_field_modification_events == 1; 844 845 case ArtJvmtiEvent::kFramePop: 846 return caps.can_generate_frame_pop_events == 1; 847 848 case ArtJvmtiEvent::kGarbageCollectionStart: 849 case ArtJvmtiEvent::kGarbageCollectionFinish: 850 return caps.can_generate_garbage_collection_events == 1; 851 852 case ArtJvmtiEvent::kMethodEntry: 853 return caps.can_generate_method_entry_events == 1; 854 855 case ArtJvmtiEvent::kMethodExit: 856 return caps.can_generate_method_exit_events == 1; 857 858 case ArtJvmtiEvent::kMonitorContendedEnter: 859 case ArtJvmtiEvent::kMonitorContendedEntered: 860 case ArtJvmtiEvent::kMonitorWait: 861 case ArtJvmtiEvent::kMonitorWaited: 862 return caps.can_generate_monitor_events == 1; 863 864 case ArtJvmtiEvent::kNativeMethodBind: 865 return caps.can_generate_native_method_bind_events == 1; 866 867 case ArtJvmtiEvent::kObjectFree: 868 return caps.can_generate_object_free_events == 1; 869 870 case ArtJvmtiEvent::kSingleStep: 871 return caps.can_generate_single_step_events == 1; 872 873 case ArtJvmtiEvent::kVmObjectAlloc: 874 return caps.can_generate_vm_object_alloc_events == 1; 875 876 default: 877 return true; 878 } 879} 880 881jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env, 882 art::Thread* thread, 883 ArtJvmtiEvent event, 884 jvmtiEventMode mode) { 885 if (thread != nullptr) { 886 art::ThreadState state = thread->GetState(); 887 if (state == art::ThreadState::kStarting || 888 state == art::ThreadState::kTerminated || 889 thread->IsStillStarting()) { 890 return ERR(THREAD_NOT_ALIVE); 891 } 892 if (!IsThreadControllable(event)) { 893 return ERR(ILLEGAL_ARGUMENT); 894 } 895 } 896 897 if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) { 898 return ERR(ILLEGAL_ARGUMENT); 899 } 900 901 if (!EventMask::EventIsInRange(event)) { 902 return ERR(INVALID_EVENT_TYPE); 903 } 904 905 if (!HasAssociatedCapability(env, event)) { 906 return ERR(MUST_POSSESS_CAPABILITY); 907 } 908 909 bool old_state = global_mask.Test(event); 910 911 if (mode == JVMTI_ENABLE) { 912 env->event_masks.EnableEvent(thread, event); 913 global_mask.Set(event); 914 } else { 915 DCHECK_EQ(mode, JVMTI_DISABLE); 916 917 env->event_masks.DisableEvent(thread, event); 918 RecalculateGlobalEventMask(event); 919 } 920 921 bool new_state = global_mask.Test(event); 922 923 // Handle any special work required for the event type. 924 if (new_state != old_state) { 925 HandleEventType(event, mode == JVMTI_ENABLE); 926 } 927 928 return ERR(NONE); 929} 930 931void EventHandler::Shutdown() { 932 // Need to remove the method_trace_listener_ if it's there. 933 art::Thread* self = art::Thread::Current(); 934 art::gc::ScopedGCCriticalSection gcs(self, 935 art::gc::kGcCauseInstrumentation, 936 art::gc::kCollectorTypeInstrumentation); 937 art::ScopedSuspendAll ssa("jvmti method tracing uninstallation"); 938 // Just remove every possible event. 939 art::Runtime::Current()->GetInstrumentation()->RemoveListener(method_trace_listener_.get(), ~0); 940} 941 942EventHandler::EventHandler() { 943 alloc_listener_.reset(new JvmtiAllocationListener(this)); 944 gc_pause_listener_.reset(new JvmtiGcPauseListener(this)); 945 method_trace_listener_.reset(new JvmtiMethodTraceListener(this)); 946} 947 948EventHandler::~EventHandler() { 949} 950 951} // namespace openjdkjvmti 952