Reland "Update instrumentation support for non-java debuggable runtimes"

This reverts commit 7cc22bb96e4e05cf63661eed7fd3dda5304bdacc.

Reason for revert: Relanding after a fix for jit-on-first-use failures.
The fix:
1. When shutting down jvmti agent, pause Jit threads and discard all
   JITed code.
2. Update the jit compiler options when transitioning the runtime debug
   state.

Change-Id: I076098459cc5639f9e87dae620a9297460e729e2
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index e578d3b..f12a3ad 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -41,6 +41,10 @@
   return new JitCompiler();
 }
 
+void JitCompiler::SetDebuggableCompilerOption(bool value) {
+  compiler_options_->SetDebuggable(value);
+}
+
 void JitCompiler::ParseCompilerOptions() {
   // Special case max code units for inlining, whose default is "unset" (implictly
   // meaning no limit). Do this before parsing the actual passed options.
diff --git a/compiler/jit/jit_compiler.h b/compiler/jit/jit_compiler.h
index 8e9966d..8cd6b5a 100644
--- a/compiler/jit/jit_compiler.h
+++ b/compiler/jit/jit_compiler.h
@@ -50,6 +50,8 @@
 
   bool IsBaselineCompiler() const override;
 
+  void SetDebuggableCompilerOption(bool val) override;
+
   bool GenerateDebugInfo() override;
 
   void ParseCompilerOptions() override;
diff --git a/openjdkjvmti/OpenjdkJvmTi.cc b/openjdkjvmti/OpenjdkJvmTi.cc
index 09900e1..d7db3d2 100644
--- a/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/openjdkjvmti/OpenjdkJvmTi.cc
@@ -89,12 +89,6 @@
     }                           \
   } while (false)
 
-// Returns whether we are able to use all jvmti features.
-static bool IsFullJvmtiAvailable() {
-  art::Runtime* runtime = art::Runtime::Current();
-  return runtime->GetInstrumentation()->IsForcedInterpretOnly() || runtime->IsJavaDebuggable();
-}
-
 class JvmtiFunctions {
  private:
   static jvmtiError getEnvironmentError(jvmtiEnv* env) {
@@ -1474,13 +1468,7 @@
   FieldUtil::Register(gEventHandler);
   BreakpointUtil::Register(gEventHandler);
   Transformer::Register(gEventHandler);
-
-  {
-    // Make sure we can deopt anything we need to.
-    art::ScopedSuspendAll ssa(__FUNCTION__);
-    gDeoptManager->FinishSetup();
-  }
-
+  gDeoptManager->FinishSetup();
   runtime->GetJavaVM()->AddEnvironmentHook(GetEnvHandler);
 
   return true;
diff --git a/openjdkjvmti/art_jvmti.h b/openjdkjvmti/art_jvmti.h
index cdda09b..bc965a2 100644
--- a/openjdkjvmti/art_jvmti.h
+++ b/openjdkjvmti/art_jvmti.h
@@ -47,9 +47,11 @@
 #include "base/strlcpy.h"
 #include "base/mutex.h"
 #include "events.h"
+#include "instrumentation.h"
 #include "jni/java_vm_ext.h"
 #include "jni/jni_env_ext.h"
 #include "jvmti.h"
+#include "runtime.h"
 #include "ti_breakpoint.h"
 
 namespace art {
@@ -69,6 +71,13 @@
 // This is the value 0x70010200.
 static constexpr jint kArtTiVersion = JVMTI_VERSION_1_2 | 0x40000000;
 
+// Returns whether we are able to use all jvmti features.
+static inline bool IsFullJvmtiAvailable() {
+  art::Runtime* runtime = art::Runtime::Current();
+  return runtime->GetInstrumentation()->IsForcedInterpretOnly() ||
+         runtime->IsJavaDebuggableAtInit();
+}
+
 // A structure that is a jvmtiEnv with additional information for the runtime.
 struct ArtJvmTiEnv : public jvmtiEnv {
   art::JavaVMExt* art_vm;
diff --git a/openjdkjvmti/deopt_manager.cc b/openjdkjvmti/deopt_manager.cc
index 03042ec..129aa0f 100644
--- a/openjdkjvmti/deopt_manager.cc
+++ b/openjdkjvmti/deopt_manager.cc
@@ -47,10 +47,12 @@
 #include "gc/scoped_gc_critical_section.h"
 #include "instrumentation.h"
 #include "jit/jit.h"
+#include "jit/jit_code_cache.h"
 #include "jni/jni_internal.h"
 #include "mirror/class-inl.h"
 #include "mirror/object_array-inl.h"
 #include "nativehelper/scoped_local_ref.h"
+#include "oat_file_manager.h"
 #include "read_barrier_config.h"
 #include "runtime_callbacks.h"
 #include "scoped_thread_state_change-inl.h"
@@ -61,6 +63,8 @@
 
 namespace openjdkjvmti {
 
+static constexpr const char* kInstrumentationKey = "JVMTI_DeoptRequester";
+
 // We could make this much more selective in the future so we only return true when we
 // actually care about the method at this time (ie active frames had locals changed). For now we
 // just assume that if anything has changed any frame's locals we care about all methods. This only
@@ -91,14 +95,6 @@
   callbacks->AddMethodInspectionCallback(&inspection_callback_);
 }
 
-void DeoptManager::Shutdown() {
-  art::ScopedThreadStateChange stsc(art::Thread::Current(),
-                                    art::ThreadState::kWaitingForDebuggerToAttach);
-  art::ScopedSuspendAll ssa("remove method Inspection Callback");
-  art::RuntimeCallbacks* callbacks = art::Runtime::Current()->GetRuntimeCallbacks();
-  callbacks->RemoveMethodInspectionCallback(&inspection_callback_);
-}
-
 void DeoptManager::DumpDeoptInfo(art::Thread* self, std::ostream& stream) {
   art::ScopedObjectAccess soa(self);
   art::MutexLock mutll(self, *art::Locks::thread_list_lock_);
@@ -148,48 +144,59 @@
 
 void DeoptManager::FinishSetup() {
   art::Thread* self = art::Thread::Current();
-  art::MutexLock mu(self, deoptimization_status_lock_);
-
   art::Runtime* runtime = art::Runtime::Current();
-  // See if we need to do anything.
-  if (!runtime->IsJavaDebuggable()) {
-    // See if we can enable all JVMTI functions. If this is false, only kArtTiVersion agents can be
-    // retrieved and they will all be best-effort.
-    if (PhaseUtil::GetPhaseUnchecked() == JVMTI_PHASE_ONLOAD) {
-      // We are still early enough to change the compiler options and get full JVMTI support.
-      LOG(INFO) << "Openjdkjvmti plugin loaded on a non-debuggable runtime. Changing runtime to "
-                << "debuggable state. Please pass '--debuggable' to dex2oat and "
-                << "'-Xcompiler-option --debuggable' to dalvikvm in the future.";
-      DCHECK(runtime->GetJit() == nullptr) << "Jit should not be running yet!";
-      runtime->AddCompilerOption("--debuggable");
-      runtime->SetJavaDebuggable(true);
-    } else {
-      LOG(WARNING) << "Openjdkjvmti plugin was loaded on a non-debuggable Runtime. Plugin was "
-                   << "loaded too late to change runtime state to DEBUGGABLE. Only kArtTiVersion "
-                   << "(0x" << std::hex << kArtTiVersion << ") environments are available. Some "
-                   << "functionality might not work properly.";
-      if (runtime->GetJit() == nullptr &&
-          runtime->GetJITOptions()->UseJitCompilation() &&
-          !runtime->GetInstrumentation()->IsForcedInterpretOnly()) {
-        // If we don't have a jit we should try to start the jit for performance reasons. We only
-        // need to do this for late attach on non-debuggable processes because for debuggable
-        // processes we already rely on jit and we cannot force this jit to start if we are still in
-        // OnLoad since the runtime hasn't started up sufficiently. This is only expected to happen
-        // on userdebug/eng builds.
-        LOG(INFO) << "Attempting to start jit for openjdkjvmti plugin.";
-        // Note: use rwx allowed = true, because if this is the system server, we will not be
-        //       allowed to allocate any JIT code cache, anyways.
-        runtime->CreateJitCodeCache(/*rwx_memory_allowed=*/true);
-        runtime->CreateJit();
-        if (runtime->GetJit() == nullptr) {
-          LOG(WARNING) << "Could not start jit for openjdkjvmti plugin. This process might be "
-                       << "quite slow as it is running entirely in the interpreter. Try running "
-                       << "'setenforce 0' and restarting this process.";
-        }
-      }
-    }
-    runtime->DeoptimizeBootImage();
+  if (runtime->IsJavaDebuggable()) {
+    return;
   }
+
+  // See if we can enable all JVMTI functions.
+  if (PhaseUtil::GetPhaseUnchecked() == JVMTI_PHASE_ONLOAD) {
+    // We are still early enough to change the compiler options and get full JVMTI support.
+    LOG(INFO) << "Openjdkjvmti plugin loaded on a non-debuggable runtime. Changing runtime to "
+              << "debuggable state. Please pass '--debuggable' to dex2oat and "
+              << "'-Xcompiler-option --debuggable' to dalvikvm in the future.";
+    DCHECK(runtime->GetJit() == nullptr) << "Jit should not be running yet!";
+    art::ScopedSuspendAll ssa(__FUNCTION__);
+    // TODO check if we need to hold deoptimization_status_lock_ here.
+    art::MutexLock mu(self, deoptimization_status_lock_);
+    runtime->AddCompilerOption("--debuggable");
+    runtime->SetRuntimeDebugState(art::Runtime::RuntimeDebugState::kJavaDebuggableAtInit);
+    runtime->DeoptimizeBootImage();
+    return;
+  }
+
+  // Runtime has already started in non-debuggable mode. Only kArtTiVersion agents can be
+  // retrieved and they will all be best-effort.
+  LOG(WARNING) << "Openjdkjvmti plugin was loaded on a non-debuggable Runtime. Plugin was "
+               << "loaded too late to change runtime state to support all capabilities. Only "
+               << "kArtTiVersion (0x" << std::hex << kArtTiVersion << ") environments are "
+               << "available. Some functionality might not work properly.";
+
+  // Transition the runtime to debuggable:
+  // 1. Wait for any background verification tasks to finish. We don't support
+  // background verification after moving to debuggable state.
+  runtime->GetOatFileManager().WaitForBackgroundVerificationTasksToFinish();
+
+  // Do the transition in ScopedJITSuspend, so we don't start any JIT compilations
+  // before the transition to debuggable is finished.
+  art::jit::ScopedJitSuspend suspend_jit;
+  art::ScopedSuspendAll ssa(__FUNCTION__);
+
+  // 2. Discard any JITed code that was generated before, since they would be
+  // compiled without debug support.
+  art::jit::Jit* jit = runtime->GetJit();
+  if (jit != nullptr) {
+    jit->GetCodeCache()->InvalidateAllCompiledCode();
+    jit->GetCodeCache()->TransitionToDebuggable();
+    jit->GetJitCompiler()->SetDebuggableCompilerOption(true);
+  }
+
+  // 3. Change the state to JavaDebuggable, so that debug features can be
+  // enabled from now on.
+  runtime->SetRuntimeDebugState(art::Runtime::RuntimeDebugState::kJavaDebuggable);
+
+  // 4. Update all entrypoints to avoid using any AOT code.
+  runtime->GetInstrumentation()->UpdateEntrypointsForDebuggable();
 }
 
 bool DeoptManager::MethodHasBreakpoints(art::ArtMethod* method) {
@@ -362,6 +369,39 @@
   }
 }
 
+void DeoptManager::Shutdown() {
+  art::Thread* self = art::Thread::Current();
+  art::Runtime* runtime = art::Runtime::Current();
+
+  // Do the transition in ScopedJITSuspend, so we don't start any JIT compilations
+  // before the transition to debuggable is finished.
+  art::jit::ScopedJitSuspend suspend_jit;
+
+  art::ScopedThreadStateChange sts(self, art::ThreadState::kSuspended);
+  deoptimization_status_lock_.ExclusiveLock(self);
+  ScopedDeoptimizationContext sdc(self, this);
+
+  art::jit::Jit* jit = runtime->GetJit();
+  if (jit != nullptr && !runtime->IsShuttingDown(self)) {
+    jit->GetCodeCache()->InvalidateAllCompiledCode();
+    jit->GetCodeCache()->TransitionToDebuggable();
+    jit->GetJitCompiler()->SetDebuggableCompilerOption(false);
+  }
+
+  art::RuntimeCallbacks* callbacks = runtime->GetRuntimeCallbacks();
+  callbacks->RemoveMethodInspectionCallback(&inspection_callback_);
+  if (!runtime->IsJavaDebuggableAtInit()) {
+    runtime->SetRuntimeDebugState(art::Runtime::RuntimeDebugState::kNonJavaDebuggable);
+  }
+  // TODO(mythria): DeoptManager should use only one key. Merge
+  // kInstrumentationKey and kDeoptManagerInstrumentationKey.
+  if (!runtime->IsShuttingDown(self)) {
+    art::Runtime::Current()->GetInstrumentation()->DisableDeoptimization(kInstrumentationKey);
+    art::Runtime::Current()->GetInstrumentation()->DisableDeoptimization(
+        kDeoptManagerInstrumentationKey);
+  }
+}
+
 void DeoptManager::RemoveDeoptimizeAllMethodsLocked(art::Thread* self) {
   DCHECK_GT(global_deopt_count_, 0u) << "Request to remove non-existent global deoptimization!";
   global_deopt_count_--;
@@ -435,7 +475,6 @@
   return OK;
 }
 
-static constexpr const char* kInstrumentationKey = "JVMTI_DeoptRequester";
 
 void DeoptManager::RemoveDeoptimizationRequester() {
   art::Thread* self = art::Thread::Current();
diff --git a/openjdkjvmti/deopt_manager.h b/openjdkjvmti/deopt_manager.h
index 9278bf1..e9b91de 100644
--- a/openjdkjvmti/deopt_manager.h
+++ b/openjdkjvmti/deopt_manager.h
@@ -110,9 +110,7 @@
       REQUIRES_SHARED(art::Locks::mutator_lock_);
   void DeoptimizeAllThreads() REQUIRES_SHARED(art::Locks::mutator_lock_);
 
-  void FinishSetup()
-      REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_)
-      REQUIRES(art::Locks::mutator_lock_);
+  void FinishSetup() REQUIRES(!deoptimization_status_lock_, !art::Roles::uninterruptible_);
 
   static DeoptManager* Get();
 
diff --git a/openjdkjvmti/ti_extension.cc b/openjdkjvmti/ti_extension.cc
index 10ea43a..02dc9f1 100644
--- a/openjdkjvmti/ti_extension.cc
+++ b/openjdkjvmti/ti_extension.cc
@@ -398,8 +398,7 @@
 
   // These require index-ids and debuggable to function
   art::Runtime* runtime = art::Runtime::Current();
-  if (runtime->GetJniIdType() == art::JniIdType::kIndices &&
-      (runtime->GetInstrumentation()->IsForcedInterpretOnly() || runtime->IsJavaDebuggable())) {
+  if (runtime->GetJniIdType() == art::JniIdType::kIndices && IsFullJvmtiAvailable()) {
     // IsStructurallyModifiableClass
     error = add_extension(
         reinterpret_cast<jvmtiExtensionFunction>(Redefiner::IsStructurallyModifiableClass),
@@ -703,8 +702,7 @@
     return error;
   }
   art::Runtime* runtime = art::Runtime::Current();
-  if (runtime->GetJniIdType() == art::JniIdType::kIndices &&
-      (runtime->GetInstrumentation()->IsForcedInterpretOnly() || runtime->IsJavaDebuggable())) {
+  if (runtime->GetJniIdType() == art::JniIdType::kIndices && IsFullJvmtiAvailable()) {
     error = add_extension(
         ArtJvmtiEvent::kStructuralDexFileLoadHook,
         "com.android.art.class.structural_dex_file_load_hook",
diff --git a/runtime/hidden_api.h b/runtime/hidden_api.h
index 1eb5e17..8688a6d 100644
--- a/runtime/hidden_api.h
+++ b/runtime/hidden_api.h
@@ -123,7 +123,7 @@
 
     if (domain == Domain::kApplication &&
         klass->ShouldSkipHiddenApiChecks() &&
-        Runtime::Current()->IsJavaDebuggable()) {
+        Runtime::Current()->IsJavaDebuggableAtInit()) {
       // Class is known, it is marked trusted and we are in debuggable mode.
       domain = ComputeDomain(/* is_trusted= */ true);
     }
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 8735dcf..6359579 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -170,7 +170,6 @@
   return !new_exception_thrown;
 }
 
-
 void Instrumentation::InstallStubsForClass(ObjPtr<mirror::Class> klass) {
   if (!klass->IsResolved()) {
     // We need the class to be resolved to install/uninstall stubs. Otherwise its methods
@@ -450,6 +449,14 @@
   UpdateEntryPoints(method, GetOptimizedCodeFor(method));
 }
 
+void Instrumentation::UpdateEntrypointsForDebuggable() {
+  Runtime* runtime = Runtime::Current();
+  // If we are transitioning from non-debuggable to debuggable, we patch
+  // entry points of methods to remove any aot / JITed entry points.
+  InstallStubsClassVisitor visitor(this);
+  runtime->GetClassLinker()->VisitClasses(&visitor);
+}
+
 // Places the instrumentation exit pc as the return PC for every quick frame. This also allows
 // deoptimization of quick frames to interpreter frames. When force_deopt is
 // true the frames have to be deoptimized. If the frame has a deoptimization
@@ -998,17 +1005,15 @@
   Locks::mutator_lock_->AssertExclusiveHeld(self);
   Locks::thread_list_lock_->AssertNotHeld(self);
   UpdateInstrumentationLevel(requested_level);
+  InstallStubsClassVisitor visitor(this);
+  runtime->GetClassLinker()->VisitClasses(&visitor);
   if (requested_level > InstrumentationLevel::kInstrumentNothing) {
-    InstallStubsClassVisitor visitor(this);
-    runtime->GetClassLinker()->VisitClasses(&visitor);
     instrumentation_stubs_installed_ = true;
     MutexLock mu(self, *Locks::thread_list_lock_);
     for (Thread* thread : Runtime::Current()->GetThreadList()->GetList()) {
       InstrumentThreadStack(thread, /* deopt_all_frames= */ false);
     }
   } else {
-    InstallStubsClassVisitor visitor(this);
-    runtime->GetClassLinker()->VisitClasses(&visitor);
     MaybeRestoreInstrumentationStack();
   }
 }
@@ -1223,6 +1228,14 @@
     return;
   }
 
+  if (method->IsObsolete()) {
+    // Don't update entry points for obsolete methods. The entrypoint should
+    // have been set to InvokeObsoleteMethoStub.
+    DCHECK_EQ(method->GetEntryPointFromQuickCompiledCodePtrSize(kRuntimePointerSize),
+              GetInvokeObsoleteMethodStub());
+    return;
+  }
+
   // We are not using interpreter stubs for deoptimization. Restore the code of the method.
   // We still retain interpreter bridge if we need it for other reasons.
   if (InterpretOnly(method)) {
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index 23c433e..b232422 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -550,6 +550,8 @@
 
   void InstallStubsForMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
 
+  void UpdateEntrypointsForDebuggable() REQUIRES(art::Locks::mutator_lock_);
+
   // Install instrumentation exit stub on every method of the stack of the given thread.
   // This is used by:
   //  - the debugger to cause a deoptimization of the all frames in thread's stack (for
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index fd92451..c95fd9d 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -196,6 +196,7 @@
   virtual bool GenerateDebugInfo() = 0;
   virtual void ParseCompilerOptions() = 0;
   virtual bool IsBaselineCompiler() const = 0;
+  virtual void SetDebuggableCompilerOption(bool value) = 0;
 
   virtual std::vector<uint8_t> PackElfFileForJIT(ArrayRef<const JITCodeEntry*> elf_files,
                                                  ArrayRef<const void*> removed_symbols,
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 39f165d..ad8cc9a 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -1763,6 +1763,18 @@
       Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(meth, /*aot_code=*/ nullptr);
     }
   }
+
+  for (auto it : zygote_map_) {
+    if (it.method == nullptr) {
+      continue;
+    }
+    if (it.method->IsPreCompiled()) {
+      it.method->ClearPreCompiled();
+    }
+    Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(it.method,
+                                                                    /*aot_code=*/nullptr);
+  }
+
   saved_compiled_methods_map_.clear();
   osr_code_map_.clear();
 }
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index d714206..9b6fb3e 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -904,7 +904,7 @@
   ScopedObjectAccess soa(env);
 
   // Currently only allow this for debuggable apps.
-  if (!runtime->IsJavaDebuggable()) {
+  if (!runtime->IsJavaDebuggableAtInit()) {
     ThrowSecurityException("Can't exempt class, process is not debuggable.");
     return;
   }
diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc
index 2e09c9f..1d5ac02 100644
--- a/runtime/native/dalvik_system_VMDebug.cc
+++ b/runtime/native/dalvik_system_VMDebug.cc
@@ -466,7 +466,7 @@
   Runtime* runtime = Runtime::Current();
   ScopedObjectAccess soa(env);
 
-  if (!runtime->IsJavaDebuggable()) {
+  if (!runtime->IsJavaDebuggableAtInit()) {
     ThrowSecurityException("Can't exempt class, process is not debuggable.");
     return;
   }
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index eae7c20..d6b40c6 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -205,7 +205,7 @@
   if ((runtime_flags & DEBUG_JAVA_DEBUGGABLE) != 0) {
     runtime->AddCompilerOption("--debuggable");
     runtime_flags |= DEBUG_GENERATE_MINI_DEBUG_INFO;
-    runtime->SetJavaDebuggable(true);
+    runtime->SetRuntimeDebugState(Runtime::RuntimeDebugState::kJavaDebuggableAtInit);
     {
       // Deoptimize the boot image as it may be non-debuggable.
       ScopedSuspendAll ssa(__FUNCTION__);
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index 6f1e95a..dfb9eaf 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -836,6 +836,15 @@
   verification_thread_pool_.reset(nullptr);
 }
 
+void OatFileManager::WaitForBackgroundVerificationTasksToFinish() {
+  if (verification_thread_pool_ == nullptr) {
+    return;
+  }
+
+  Thread* const self = Thread::Current();
+  verification_thread_pool_->Wait(self, /* do_work= */ true, /* may_hold_locks= */ false);
+}
+
 void OatFileManager::WaitForBackgroundVerificationTasks() {
   if (verification_thread_pool_ != nullptr) {
     Thread* const self = Thread::Current();
diff --git a/runtime/oat_file_manager.h b/runtime/oat_file_manager.h
index b73ac58..e09390b 100644
--- a/runtime/oat_file_manager.h
+++ b/runtime/oat_file_manager.h
@@ -134,6 +134,9 @@
   // If allocated, delete a thread pool of background verification threads.
   void DeleteThreadPool();
 
+  // Wait for any ongoing background verification tasks to finish.
+  void WaitForBackgroundVerificationTasksToFinish();
+
   // Wait for all background verification tasks to finish. This is only used by tests.
   void WaitForBackgroundVerificationTasks();
 
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 6e583af..b291e7d 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -288,7 +288,7 @@
       is_native_debuggable_(false),
       async_exceptions_thrown_(false),
       non_standard_exits_enabled_(false),
-      is_java_debuggable_(false),
+      runtime_debug_state_(RuntimeDebugState::kNonJavaDebuggable),
       monitor_timeout_enable_(false),
       monitor_timeout_ns_(0),
       zygote_max_failed_boots_(0),
@@ -1543,7 +1543,7 @@
   compiler_options_ = runtime_options.ReleaseOrDefault(Opt::CompilerOptions);
   for (const std::string& option : Runtime::Current()->GetCompilerOptions()) {
     if (option == "--debuggable") {
-      SetJavaDebuggable(true);
+      SetRuntimeDebugState(RuntimeDebugState::kJavaDebuggableAtInit);
       break;
     }
   }
@@ -3226,9 +3226,12 @@
   instrumentation::Instrumentation* const instrumentation_;
 };
 
-void Runtime::SetJavaDebuggable(bool value) {
-  is_java_debuggable_ = value;
-  // Do not call DeoptimizeBootImage just yet, the runtime may still be starting up.
+void Runtime::SetRuntimeDebugState(RuntimeDebugState state) {
+  if (state != RuntimeDebugState::kJavaDebuggableAtInit) {
+    // We never change the state if we started as a debuggable runtime.
+    DCHECK(runtime_debug_state_ != RuntimeDebugState::kJavaDebuggableAtInit);
+  }
+  runtime_debug_state_ = state;
 }
 
 void Runtime::DeoptimizeBootImage() {
diff --git a/runtime/runtime.h b/runtime/runtime.h
index a932718..4790c9e 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -133,6 +133,19 @@
   static bool Create(const RuntimeOptions& raw_options, bool ignore_unrecognized)
       SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_);
 
+  enum class RuntimeDebugState {
+    // This doesn't support any debug features / method tracing. This is the expected state usually.
+    kNonJavaDebuggable,
+    // This supports method tracing and a restricted set of debug features (for ex: redefinition
+    // isn't supported). We transition to this state when method tracing has started or when the
+    // debugger was attached and transition back to NonDebuggable once the tracing has stopped /
+    // the debugger agent has detached..
+    kJavaDebuggable,
+    // The runtime was started as a debuggable runtime. This allows us to support the extended set
+    // of debug features (for ex: redefinition). We never transition out of this state.
+    kJavaDebuggableAtInit
+  };
+
   bool EnsurePluginLoaded(const char* plugin_name, std::string* error_msg);
   bool EnsurePerfettoPlugin(std::string* error_msg);
 
@@ -806,7 +819,12 @@
   }
 
   bool IsJavaDebuggable() const {
-    return is_java_debuggable_;
+    return runtime_debug_state_ == RuntimeDebugState::kJavaDebuggable ||
+           runtime_debug_state_ == RuntimeDebugState::kJavaDebuggableAtInit;
+  }
+
+  bool IsJavaDebuggableAtInit() const {
+    return runtime_debug_state_ == RuntimeDebugState::kJavaDebuggableAtInit;
   }
 
   void SetProfileableFromShell(bool value) {
@@ -825,7 +843,7 @@
     return is_profileable_;
   }
 
-  void SetJavaDebuggable(bool value);
+  void SetRuntimeDebugState(RuntimeDebugState state);
 
   // Deoptimize the boot image, called for Java debuggable apps.
   void DeoptimizeBootImage() REQUIRES(Locks::mutator_lock_);
@@ -1375,7 +1393,7 @@
   bool non_standard_exits_enabled_;
 
   // Whether Java code needs to be debuggable.
-  bool is_java_debuggable_;
+  RuntimeDebugState runtime_debug_state_;
 
   bool monitor_timeout_enable_;
   uint64_t monitor_timeout_ns_;
diff --git a/runtime/trace.cc b/runtime/trace.cc
index 6b4fb29..edca549 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -431,8 +431,8 @@
         // we know that inlining and other problematic optimizations are disabled. We might just
         // want to use the trampolines anyway since it is faster. It makes the story with disabling
         // jit-gc more complex though.
-        runtime->GetInstrumentation()->EnableMethodTracing(
-            kTracerInstrumentationKey, /*needs_interpreter=*/!runtime->IsJavaDebuggable());
+        runtime->GetInstrumentation()->EnableMethodTracing(kTracerInstrumentationKey,
+                                                           /*needs_interpreter=*/false);
       }
     }
   }
diff --git a/test/2031-zygote-compiled-frame-deopt/native-wait.cc b/test/2031-zygote-compiled-frame-deopt/native-wait.cc
index bd1d224..fb45345 100644
--- a/test/2031-zygote-compiled-frame-deopt/native-wait.cc
+++ b/test/2031-zygote-compiled-frame-deopt/native-wait.cc
@@ -42,7 +42,7 @@
   }
   runtime->SetAsZygoteChild(/*is_system_server=*/false, /*is_zygote=*/false);
   runtime->AddCompilerOption("--debuggable");
-  runtime->SetJavaDebuggable(true);
+  runtime->SetRuntimeDebugState(Runtime::RuntimeDebugState::kJavaDebuggableAtInit);
   {
     // Deoptimize the boot image as it may be non-debuggable.
     ScopedSuspendAll ssa(__FUNCTION__);
diff --git a/test/993-breakpoints-non-debuggable/Android.bp b/test/993-breakpoints-non-debuggable/Android.bp
new file mode 100644
index 0000000..53a9f28
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/Android.bp
@@ -0,0 +1,40 @@
+// Generated by `regen-test-files`. Do not edit manually.
+
+// Build rules for ART run-test `993-breakpoints-non-debuggable`.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "art_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["art_license"],
+}
+
+// Test's Dex code.
+java_test {
+    name: "art-run-test-993-breakpoints-non-debuggable",
+    defaults: ["art-run-test-defaults"],
+    test_config_template: ":art-run-test-target-no-test-suite-tag-template",
+    srcs: ["src/**/*.java"],
+    data: [
+        ":art-run-test-993-breakpoints-non-debuggable-expected-stdout",
+        ":art-run-test-993-breakpoints-non-debuggable-expected-stderr",
+    ],
+}
+
+// Test's expected standard output.
+genrule {
+    name: "art-run-test-993-breakpoints-non-debuggable-expected-stdout",
+    out: ["art-run-test-993-breakpoints-non-debuggable-expected-stdout.txt"],
+    srcs: ["expected-stdout.txt"],
+    cmd: "cp -f $(in) $(out)",
+}
+
+// Test's expected standard error.
+genrule {
+    name: "art-run-test-993-breakpoints-non-debuggable-expected-stderr",
+    out: ["art-run-test-993-breakpoints-non-debuggable-expected-stderr.txt"],
+    srcs: ["expected-stderr.txt"],
+    cmd: "cp -f $(in) $(out)",
+}
diff --git a/test/993-breakpoints-non-debuggable/expected-stderr.txt b/test/993-breakpoints-non-debuggable/expected-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/expected-stderr.txt
diff --git a/test/993-breakpoints-non-debuggable/expected-stdout.txt b/test/993-breakpoints-non-debuggable/expected-stdout.txt
new file mode 100644
index 0000000..a4bd24b
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/expected-stdout.txt
@@ -0,0 +1,715 @@
+JNI_OnLoad called
+Running static invoke
+	Breaking on []
+		Native invoking: public static void art.Test993.breakpoint() args: [this: null]
+		Reflective invoking: public static void art.Test993.breakpoint() args: [this: null]
+		Invoking "Test993::breakpoint"
+	Breaking on [public static void art.Test993.breakpoint() @ 41]
+		Native invoking: public static void art.Test993.breakpoint() args: [this: null]
+			Breakpoint: public static void art.Test993.breakpoint() @ line=41
+		Reflective invoking: public static void art.Test993.breakpoint() args: [this: null]
+			Breakpoint: public static void art.Test993.breakpoint() @ line=41
+		Invoking "Test993::breakpoint"
+			Breakpoint: public static void art.Test993.breakpoint() @ line=41
+Running private static invoke
+	Breaking on []
+		Native invoking: private static void art.Test993.privateBreakpoint() args: [this: null]
+		Invoking "Test993::privateBreakpoint"
+	Breaking on [private static void art.Test993.privateBreakpoint() @ 45]
+		Native invoking: private static void art.Test993.privateBreakpoint() args: [this: null]
+			Breakpoint: private static void art.Test993.privateBreakpoint() @ line=45
+		Invoking "Test993::privateBreakpoint"
+			Breakpoint: private static void art.Test993.privateBreakpoint() @ line=45
+Running interface static invoke
+	Breaking on []
+		Native invoking: public static void art.Test993$Breakable.iBreakpoint() args: [this: null]
+		Reflective invoking: public static void art.Test993$Breakable.iBreakpoint() args: [this: null]
+		Invoking "Breakable::iBreakpoint"
+	Breaking on [public static void art.Test993$Breakable.iBreakpoint() @ 51]
+		Native invoking: public static void art.Test993$Breakable.iBreakpoint() args: [this: null]
+			Breakpoint: public static void art.Test993$Breakable.iBreakpoint() @ line=51
+		Reflective invoking: public static void art.Test993$Breakable.iBreakpoint() args: [this: null]
+			Breakpoint: public static void art.Test993$Breakable.iBreakpoint() @ line=51
+		Invoking "Breakable::iBreakpoint"
+			Breakpoint: public static void art.Test993$Breakable.iBreakpoint() @ line=51
+Running TestClass1 invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1]
+		Invoking "((Breakable)new TestClass1()).breakit()"
+		Invoking "new TestClass1().breakit()"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass1()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass1().breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+Running TestClass1ext invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+		Native invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+		Reflective invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+		Invoking "((Breakable)new TestClass1ext()).breakit()"
+		Invoking "((TestClass1)new TestClass1ext()).breakit()"
+		Invoking "new TestClass1ext().breakit()"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass1ext()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass1)new TestClass1ext()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass1ext().breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+	Breaking on [public void art.Test993$TestClass1ext.breakit() @ 74]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Native invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Reflective invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Invoking "((Breakable)new TestClass1ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Invoking "((TestClass1)new TestClass1ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Invoking "new TestClass1ext().breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass1ext.breakit() @ 74]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass1ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass1)new TestClass1ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass1ext().breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+Running TestClass2 invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+		Invoking "((Breakable)new TestClass2()).breakit()"
+		Invoking "new TestClass2().breakit()"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+		Invoking "((Breakable)new TestClass2()).breakit()"
+		Invoking "new TestClass2().breakit()"
+	Breaking on [public void art.Test993$TestClass2.breakit() @ 83]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2().breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass2.breakit() @ 83]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2().breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+Running TestClass2ext invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+		Invoking "new TestClass2ext().breakit())"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+		Invoking "new TestClass2ext().breakit())"
+	Breaking on [public void art.Test993$TestClass2.breakit() @ 83]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+	Breaking on [public void art.Test993$TestClass2ext.breakit() @ 91]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass2.breakit() @ 83]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass2ext.breakit() @ 91]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+	Breaking on [public void art.Test993$TestClass2.breakit() @ 83, public void art.Test993$TestClass2ext.breakit() @ 91]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass2.breakit() @ 83, public void art.Test993$TestClass2ext.breakit() @ 91]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+Running TestClass3 invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+		Invoking "((Breakable)new TestClass3()).breakit()"
+		Invoking "new TestClass3().breakit())"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3().breakit())"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+	Breaking on [public void art.Test993$TestClass3.breakit() @ 99]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "((Breakable)new TestClass3()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "new TestClass3().breakit())"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass3.breakit() @ 99]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3().breakit())"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+Running TestClass3ext invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+		Invoking "new TestClass3ext().breakit())"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+	Breaking on [public void art.Test993$TestClass3.breakit() @ 99]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+	Breaking on [public void art.Test993$TestClass3ext.breakit() @ 108]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass3.breakit() @ 99]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass3ext.breakit() @ 108]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+	Breaking on [public void art.Test993$TestClass3.breakit() @ 99, public void art.Test993$TestClass3ext.breakit() @ 108]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass3.breakit() @ 99, public void art.Test993$TestClass3ext.breakit() @ 108]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+Running private instance invoke
+	Breaking on []
+		Native invoking: private void art.Test993$TestClass4.privateMethod() args: [this: TestClass4]
+		Invoking "new TestClass4().callPrivateMethod()"
+	Breaking on [private void art.Test993$TestClass4.privateMethod() @ 118]
+		Native invoking: private void art.Test993$TestClass4.privateMethod() args: [this: TestClass4]
+			Breakpoint: private void art.Test993$TestClass4.privateMethod() @ line=118
+		Invoking "new TestClass4().callPrivateMethod()"
+			Breakpoint: private void art.Test993$TestClass4.privateMethod() @ line=118
+Running Vector constructor
+	Breaking on []
+		Native constructor: public java.util.Vector(), type: class java.util.Vector
+			Created: []
+		Reflective constructor: public java.util.Vector()
+			Created: []
+		Constructing: new Vector()
+			Created: []
+	Breaking on [public java.util.Vector() @ <NON-DETERMINISTIC>]
+		Native constructor: public java.util.Vector(), type: class java.util.Vector
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Reflective constructor: public java.util.Vector()
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Constructing: new Vector()
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+Running Stack constructor
+	Breaking on []
+		Native constructor: public java.util.Stack(), type: class java.util.Stack
+			Created: []
+		Reflective constructor: public java.util.Stack()
+			Created: []
+		Constructing: new Stack()
+			Created: []
+	Breaking on [public java.util.Stack() @ <NON-DETERMINISTIC>]
+		Native constructor: public java.util.Stack(), type: class java.util.Stack
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Reflective constructor: public java.util.Stack()
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Constructing: new Stack()
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Created: []
+	Breaking on [public java.util.Vector() @ <NON-DETERMINISTIC>]
+		Native constructor: public java.util.Stack(), type: class java.util.Stack
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Reflective constructor: public java.util.Stack()
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Constructing: new Stack()
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+	Breaking on [public java.util.Stack() @ <NON-DETERMINISTIC>, public java.util.Vector() @ <NON-DETERMINISTIC>]
+		Native constructor: public java.util.Stack(), type: class java.util.Stack
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Reflective constructor: public java.util.Stack()
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Constructing: new Stack()
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+Running bcp static invoke
+	Breaking on []
+		Native invoking: public static java.util.Optional java.util.Optional.empty() args: [this: null]
+		Reflective invoking: public static java.util.Optional java.util.Optional.empty() args: [this: null]
+		Invoking "Optional::empty"
+	Breaking on [public static java.util.Optional java.util.Optional.empty() @ <NON-DETERMINISTIC>]
+		Native invoking: public static java.util.Optional java.util.Optional.empty() args: [this: null]
+			Breakpoint: public static java.util.Optional java.util.Optional.empty() @ line=<NON-DETERMINISTIC>
+		Reflective invoking: public static java.util.Optional java.util.Optional.empty() args: [this: null]
+			Breakpoint: public static java.util.Optional java.util.Optional.empty() @ line=<NON-DETERMINISTIC>
+		Invoking "Optional::empty"
+			Breakpoint: public static java.util.Optional java.util.Optional.empty() @ line=<NON-DETERMINISTIC>
+Running bcp private static invoke
+	Breaking on []
+		Native invoking: private static long java.util.Random.seedUniquifier() args: [this: null]
+		Invoking "Random::seedUniquifier"
+	Breaking on [private static long java.util.Random.seedUniquifier() @ <NON-DETERMINISTIC>]
+		Native invoking: private static long java.util.Random.seedUniquifier() args: [this: null]
+			Breakpoint: private static long java.util.Random.seedUniquifier() @ line=<NON-DETERMINISTIC>
+		Invoking "Random::seedUniquifier"
+			Breakpoint: private static long java.util.Random.seedUniquifier() @ line=<NON-DETERMINISTIC>
+Running bcp private invoke
+	Breaking on []
+		Native invoking: private java.math.BigDecimal java.time.Duration.toBigDecimalSeconds() args: [this: PT336H]
+		Invoking "Duration::toBigDecimalSeconds"
+	Breaking on [private java.math.BigDecimal java.time.Duration.toBigDecimalSeconds() @ <NON-DETERMINISTIC>]
+		Native invoking: private java.math.BigDecimal java.time.Duration.toBigDecimalSeconds() args: [this: PT336H]
+			Breakpoint: private java.math.BigDecimal java.time.Duration.toBigDecimalSeconds() @ line=<NON-DETERMINISTIC>
+		Invoking "Duration::toBigDecimalSeconds"
+			Breakpoint: private java.math.BigDecimal java.time.Duration.toBigDecimalSeconds() @ line=<NON-DETERMINISTIC>
+Running bcp invoke
+	Breaking on []
+		Native invoking: public boolean java.util.Optional.isPresent() args: [this: Optional[test]]
+		Reflective invoking: public boolean java.util.Optional.isPresent() args: [this: Optional[test2]]
+		Invoking "Optional::isPresent"
+	Breaking on [public boolean java.util.Optional.isPresent() @ <NON-DETERMINISTIC>]
+		Native invoking: public boolean java.util.Optional.isPresent() args: [this: Optional[test]]
+			Breakpoint: public boolean java.util.Optional.isPresent() @ line=<NON-DETERMINISTIC>
+		Reflective invoking: public boolean java.util.Optional.isPresent() args: [this: Optional[test2]]
+			Breakpoint: public boolean java.util.Optional.isPresent() @ line=<NON-DETERMINISTIC>
+		Invoking "Optional::isPresent"
+			Breakpoint: public boolean java.util.Optional.isPresent() @ line=<NON-DETERMINISTIC>
+Running TestClass1 constructor
+	Breaking on []
+		Native constructor: public art.Test993$TestClass1(), type: class art.Test993$TestClass1
+			Created: TestClass1
+		Reflective constructor: public art.Test993$TestClass1()
+			Created: TestClass1
+		Constructing: new TestClass1()
+			Created: TestClass1
+	Breaking on [public art.Test993$TestClass1() @ 62]
+		Native constructor: public art.Test993$TestClass1(), type: class art.Test993$TestClass1
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1
+		Reflective constructor: public art.Test993$TestClass1()
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1
+		Constructing: new TestClass1()
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1
+Running TestClass1ext constructor
+	Breaking on []
+		Native constructor: public art.Test993$TestClass1ext(), type: class art.Test993$TestClass1ext
+			Created: TestClass1Ext
+		Reflective constructor: public art.Test993$TestClass1ext()
+			Created: TestClass1Ext
+		Constructing: new TestClass1ext()
+			Created: TestClass1Ext
+	Breaking on [public art.Test993$TestClass1() @ 62]
+		Native constructor: public art.Test993$TestClass1ext(), type: class art.Test993$TestClass1ext
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
+		Reflective constructor: public art.Test993$TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
+		Constructing: new TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
+	Breaking on [public art.Test993$TestClass1ext() @ 70]
+		Native constructor: public art.Test993$TestClass1ext(), type: class art.Test993$TestClass1ext
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Created: TestClass1Ext
+		Reflective constructor: public art.Test993$TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Created: TestClass1Ext
+		Constructing: new TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Created: TestClass1Ext
+	Breaking on [public art.Test993$TestClass1() @ 62, public art.Test993$TestClass1ext() @ 70]
+		Native constructor: public art.Test993$TestClass1ext(), type: class art.Test993$TestClass1ext
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
+		Reflective constructor: public art.Test993$TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
+		Constructing: new TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
diff --git a/test/993-breakpoints-non-debuggable/expected_cts.txt b/test/993-breakpoints-non-debuggable/expected_cts.txt
new file mode 100644
index 0000000..6c4e881
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/expected_cts.txt
@@ -0,0 +1,696 @@
+Running static invoke
+	Breaking on []
+		Native invoking: public static void art.Test993.breakpoint() args: [this: null]
+		Reflective invoking: public static void art.Test993.breakpoint() args: [this: null]
+		Invoking "Test993::breakpoint"
+	Breaking on [public static void art.Test993.breakpoint() @ 41]
+		Native invoking: public static void art.Test993.breakpoint() args: [this: null]
+			Breakpoint: public static void art.Test993.breakpoint() @ line=41
+		Reflective invoking: public static void art.Test993.breakpoint() args: [this: null]
+			Breakpoint: public static void art.Test993.breakpoint() @ line=41
+		Invoking "Test993::breakpoint"
+			Breakpoint: public static void art.Test993.breakpoint() @ line=41
+Running private static invoke
+	Breaking on []
+		Native invoking: private static void art.Test993.privateBreakpoint() args: [this: null]
+		Invoking "Test993::privateBreakpoint"
+	Breaking on [private static void art.Test993.privateBreakpoint() @ 45]
+		Native invoking: private static void art.Test993.privateBreakpoint() args: [this: null]
+			Breakpoint: private static void art.Test993.privateBreakpoint() @ line=45
+		Invoking "Test993::privateBreakpoint"
+			Breakpoint: private static void art.Test993.privateBreakpoint() @ line=45
+Running interface static invoke
+	Breaking on []
+		Native invoking: public static void art.Test993$Breakable.iBreakpoint() args: [this: null]
+		Reflective invoking: public static void art.Test993$Breakable.iBreakpoint() args: [this: null]
+		Invoking "Breakable::iBreakpoint"
+	Breaking on [public static void art.Test993$Breakable.iBreakpoint() @ 51]
+		Native invoking: public static void art.Test993$Breakable.iBreakpoint() args: [this: null]
+			Breakpoint: public static void art.Test993$Breakable.iBreakpoint() @ line=51
+		Reflective invoking: public static void art.Test993$Breakable.iBreakpoint() args: [this: null]
+			Breakpoint: public static void art.Test993$Breakable.iBreakpoint() @ line=51
+		Invoking "Breakable::iBreakpoint"
+			Breakpoint: public static void art.Test993$Breakable.iBreakpoint() @ line=51
+Running TestClass1 invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1]
+		Invoking "((Breakable)new TestClass1()).breakit()"
+		Invoking "new TestClass1().breakit()"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass1()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass1().breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+Running TestClass1ext invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+		Native invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+		Reflective invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+		Invoking "((Breakable)new TestClass1ext()).breakit()"
+		Invoking "((TestClass1)new TestClass1ext()).breakit()"
+		Invoking "new TestClass1ext().breakit()"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass1ext()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass1)new TestClass1ext()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass1ext().breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+	Breaking on [public void art.Test993$TestClass1ext.breakit() @ 74]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Native invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Reflective invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Invoking "((Breakable)new TestClass1ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Invoking "((TestClass1)new TestClass1ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+		Invoking "new TestClass1ext().breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass1ext.breakit() @ 74]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass1ext.breakit() args: [this: TestClass1Ext]
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass1ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass1)new TestClass1ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass1ext().breakit()"
+			Breakpoint: public void art.Test993$TestClass1ext.breakit() @ line=74
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+Running TestClass2 invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+		Invoking "((Breakable)new TestClass2()).breakit()"
+		Invoking "new TestClass2().breakit()"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+		Invoking "((Breakable)new TestClass2()).breakit()"
+		Invoking "new TestClass2().breakit()"
+	Breaking on [public void art.Test993$TestClass2.breakit() @ 83]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2().breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass2.breakit() @ 83]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2().breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+Running TestClass2ext invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+		Invoking "new TestClass2ext().breakit())"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+		Invoking "new TestClass2ext().breakit())"
+	Breaking on [public void art.Test993$TestClass2.breakit() @ 83]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+	Breaking on [public void art.Test993$TestClass2ext.breakit() @ 91]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass2.breakit() @ 83]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass2ext.breakit() @ 91]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+	Breaking on [public void art.Test993$TestClass2.breakit() @ 83, public void art.Test993$TestClass2ext.breakit() @ 91]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass2.breakit() @ 83, public void art.Test993$TestClass2ext.breakit() @ 91]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Native invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Reflective invoking: public void art.Test993$TestClass2ext.breakit() args: [this: TestClass2ext]
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((Breakable)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "((TestClass2)new TestClass2ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+		Invoking "new TestClass2ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass2ext.breakit() @ line=91
+			Breakpoint: public void art.Test993$TestClass2.breakit() @ line=83
+Running TestClass3 invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+		Invoking "((Breakable)new TestClass3()).breakit()"
+		Invoking "new TestClass3().breakit())"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3().breakit())"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+	Breaking on [public void art.Test993$TestClass3.breakit() @ 99]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "((Breakable)new TestClass3()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "new TestClass3().breakit())"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass3.breakit() @ 99]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3().breakit())"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+Running TestClass3ext invokes
+	Breaking on []
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+		Invoking "new TestClass3ext().breakit())"
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+	Breaking on [public void art.Test993$TestClass3.breakit() @ 99]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+	Breaking on [public void art.Test993$TestClass3ext.breakit() @ 108]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass3.breakit() @ 99]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass3ext.breakit() @ 108]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+	Breaking on [public void art.Test993$TestClass3.breakit() @ 99, public void art.Test993$TestClass3ext.breakit() @ 108]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+	Breaking on [public default void art.Test993$Breakable.breakit() @ 55, public void art.Test993$TestClass3.breakit() @ 99, public void art.Test993$TestClass3ext.breakit() @ 108]
+		Native invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Native invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public default void art.Test993$Breakable.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Reflective invoking: public void art.Test993$TestClass3ext.breakit() args: [this: TestClass3ext]
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((Breakable)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "((TestClass3)new TestClass3ext()).breakit()"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+		Invoking "new TestClass3ext().breakit())"
+			Breakpoint: public void art.Test993$TestClass3ext.breakit() @ line=108
+			Breakpoint: public void art.Test993$TestClass3.breakit() @ line=99
+			Breakpoint: public default void art.Test993$Breakable.breakit() @ line=55
+Running private instance invoke
+	Breaking on []
+		Native invoking: private void art.Test993$TestClass4.privateMethod() args: [this: TestClass4]
+		Invoking "new TestClass4().callPrivateMethod()"
+	Breaking on [private void art.Test993$TestClass4.privateMethod() @ 118]
+		Native invoking: private void art.Test993$TestClass4.privateMethod() args: [this: TestClass4]
+			Breakpoint: private void art.Test993$TestClass4.privateMethod() @ line=118
+		Invoking "new TestClass4().callPrivateMethod()"
+			Breakpoint: private void art.Test993$TestClass4.privateMethod() @ line=118
+Running Vector constructor
+	Breaking on []
+		Native constructor: public java.util.Vector(), type: class java.util.Vector
+			Created: []
+		Reflective constructor: public java.util.Vector()
+			Created: []
+		Constructing: new Vector()
+			Created: []
+	Breaking on [public java.util.Vector() @ <NON-DETERMINISTIC>]
+		Native constructor: public java.util.Vector(), type: class java.util.Vector
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Reflective constructor: public java.util.Vector()
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Constructing: new Vector()
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+Running Stack constructor
+	Breaking on []
+		Native constructor: public java.util.Stack(), type: class java.util.Stack
+			Created: []
+		Reflective constructor: public java.util.Stack()
+			Created: []
+		Constructing: new Stack()
+			Created: []
+	Breaking on [public java.util.Stack() @ <NON-DETERMINISTIC>]
+		Native constructor: public java.util.Stack(), type: class java.util.Stack
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Reflective constructor: public java.util.Stack()
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Constructing: new Stack()
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Created: []
+	Breaking on [public java.util.Vector() @ <NON-DETERMINISTIC>]
+		Native constructor: public java.util.Stack(), type: class java.util.Stack
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Reflective constructor: public java.util.Stack()
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Constructing: new Stack()
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+	Breaking on [public java.util.Stack() @ <NON-DETERMINISTIC>, public java.util.Vector() @ <NON-DETERMINISTIC>]
+		Native constructor: public java.util.Stack(), type: class java.util.Stack
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Reflective constructor: public java.util.Stack()
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+		Constructing: new Stack()
+			Breakpoint: public java.util.Stack() @ line=<NON-DETERMINISTIC>
+			Breakpoint: public java.util.Vector() @ line=<NON-DETERMINISTIC>
+			Created: []
+Running bcp static invoke
+	Breaking on []
+		Native invoking: public static java.util.Optional java.util.Optional.empty() args: [this: null]
+		Reflective invoking: public static java.util.Optional java.util.Optional.empty() args: [this: null]
+		Invoking "Optional::empty"
+	Breaking on [public static java.util.Optional java.util.Optional.empty() @ <NON-DETERMINISTIC>]
+		Native invoking: public static java.util.Optional java.util.Optional.empty() args: [this: null]
+			Breakpoint: public static java.util.Optional java.util.Optional.empty() @ line=<NON-DETERMINISTIC>
+		Reflective invoking: public static java.util.Optional java.util.Optional.empty() args: [this: null]
+			Breakpoint: public static java.util.Optional java.util.Optional.empty() @ line=<NON-DETERMINISTIC>
+		Invoking "Optional::empty"
+			Breakpoint: public static java.util.Optional java.util.Optional.empty() @ line=<NON-DETERMINISTIC>
+Running bcp invoke
+	Breaking on []
+		Native invoking: public boolean java.util.Optional.isPresent() args: [this: Optional[test]]
+		Reflective invoking: public boolean java.util.Optional.isPresent() args: [this: Optional[test2]]
+		Invoking "Optional::isPresent"
+	Breaking on [public boolean java.util.Optional.isPresent() @ <NON-DETERMINISTIC>]
+		Native invoking: public boolean java.util.Optional.isPresent() args: [this: Optional[test]]
+			Breakpoint: public boolean java.util.Optional.isPresent() @ line=<NON-DETERMINISTIC>
+		Reflective invoking: public boolean java.util.Optional.isPresent() args: [this: Optional[test2]]
+			Breakpoint: public boolean java.util.Optional.isPresent() @ line=<NON-DETERMINISTIC>
+		Invoking "Optional::isPresent"
+			Breakpoint: public boolean java.util.Optional.isPresent() @ line=<NON-DETERMINISTIC>
+Running TestClass1 constructor
+	Breaking on []
+		Native constructor: public art.Test993$TestClass1(), type: class art.Test993$TestClass1
+			Created: TestClass1
+		Reflective constructor: public art.Test993$TestClass1()
+			Created: TestClass1
+		Constructing: new TestClass1()
+			Created: TestClass1
+	Breaking on [public art.Test993$TestClass1() @ 62]
+		Native constructor: public art.Test993$TestClass1(), type: class art.Test993$TestClass1
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1
+		Reflective constructor: public art.Test993$TestClass1()
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1
+		Constructing: new TestClass1()
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1
+Running TestClass1ext constructor
+	Breaking on []
+		Native constructor: public art.Test993$TestClass1ext(), type: class art.Test993$TestClass1ext
+			Created: TestClass1Ext
+		Reflective constructor: public art.Test993$TestClass1ext()
+			Created: TestClass1Ext
+		Constructing: new TestClass1ext()
+			Created: TestClass1Ext
+	Breaking on [public art.Test993$TestClass1() @ 62]
+		Native constructor: public art.Test993$TestClass1ext(), type: class art.Test993$TestClass1ext
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
+		Reflective constructor: public art.Test993$TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
+		Constructing: new TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
+	Breaking on [public art.Test993$TestClass1ext() @ 70]
+		Native constructor: public art.Test993$TestClass1ext(), type: class art.Test993$TestClass1ext
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Created: TestClass1Ext
+		Reflective constructor: public art.Test993$TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Created: TestClass1Ext
+		Constructing: new TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Created: TestClass1Ext
+	Breaking on [public art.Test993$TestClass1() @ 62, public art.Test993$TestClass1ext() @ 70]
+		Native constructor: public art.Test993$TestClass1ext(), type: class art.Test993$TestClass1ext
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
+		Reflective constructor: public art.Test993$TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
+		Constructing: new TestClass1ext()
+			Breakpoint: public art.Test993$TestClass1ext() @ line=70
+			Breakpoint: public art.Test993$TestClass1() @ line=62
+			Created: TestClass1Ext
diff --git a/test/993-breakpoints-non-debuggable/info.txt b/test/993-breakpoints-non-debuggable/info.txt
new file mode 100644
index 0000000..b5eb546
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/info.txt
@@ -0,0 +1,7 @@
+Test basic JVMTI breakpoint functionality.
+
+This test places a breakpoint on the first instruction of a number of functions
+that are entered in every way possible for the given class of method.
+
+It also tests that breakpoints don't interfere with each other by having
+multiple breakpoints be set at once.
diff --git a/test/993-breakpoints-non-debuggable/native_attach_agent.cc b/test/993-breakpoints-non-debuggable/native_attach_agent.cc
new file mode 100644
index 0000000..71d30eb
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/native_attach_agent.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sstream>
+
+#include "jni.h"
+#include "runtime.h"
+
+namespace art {
+namespace Test993BreakpointsNonDebuggable {
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test993AttachAgent_setupJvmti(JNIEnv* env, jclass) {
+  Runtime* runtime = Runtime::Current();
+  std::ostringstream oss;
+  oss << (kIsDebugBuild ? "libtiagentd.so" : "libtiagent.so") << "=993-non-debuggable,art";
+  LOG(INFO) << "agent " << oss.str();
+  runtime->AttachAgent(env, oss.str(), nullptr);
+}
+
+}  // namespace Test993BreakpointsNonDebuggable
+}  // namespace art
diff --git a/test/993-breakpoints-non-debuggable/onload.cc b/test/993-breakpoints-non-debuggable/onload.cc
new file mode 100644
index 0000000..dbbcadc
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/onload.cc
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jvmti.h"
+#include "jvmti_helper.h"
+#include "test_env.h"
+
+namespace art {
+namespace Test993BreakpointsNonDebuggable {
+
+static constexpr jint kArtTiVersion = JVMTI_VERSION_1_2 | 0x40000000;
+
+static const jvmtiCapabilities limited_caps = {
+    .can_tag_objects = 1,
+    .can_generate_field_modification_events = 1,
+    .can_generate_field_access_events = 1,
+    .can_get_bytecodes = 1,
+    .can_get_synthetic_attribute = 1,
+    .can_get_owned_monitor_info = 0,
+    .can_get_current_contended_monitor = 1,
+    .can_get_monitor_info = 1,
+    .can_pop_frame = 0,
+    .can_redefine_classes = 0,
+    .can_signal_thread = 1,
+    .can_get_source_file_name = 1,
+    .can_get_line_numbers = 1,
+    .can_get_source_debug_extension = 1,
+    .can_access_local_variables = 0,
+    .can_maintain_original_method_order = 1,
+    .can_generate_single_step_events = 1,
+    .can_generate_exception_events = 0,
+    .can_generate_frame_pop_events = 0,
+    .can_generate_breakpoint_events = 1,
+    .can_suspend = 1,
+    .can_redefine_any_class = 0,
+    .can_get_current_thread_cpu_time = 0,
+    .can_get_thread_cpu_time = 0,
+    .can_generate_method_entry_events = 1,
+    .can_generate_method_exit_events = 1,
+    .can_generate_all_class_hook_events = 0,
+    .can_generate_compiled_method_load_events = 0,
+    .can_generate_monitor_events = 0,
+    .can_generate_vm_object_alloc_events = 1,
+    .can_generate_native_method_bind_events = 1,
+    .can_generate_garbage_collection_events = 1,
+    .can_generate_object_free_events = 1,
+    .can_force_early_return = 0,
+    .can_get_owned_monitor_stack_depth_info = 0,
+    .can_get_constant_pool = 0,
+    .can_set_native_method_prefix = 0,
+    .can_retransform_classes = 0,
+    .can_retransform_any_class = 0,
+    .can_generate_resource_exhaustion_heap_events = 0,
+    .can_generate_resource_exhaustion_threads_events = 0,
+};
+
+jint OnLoad(JavaVM* vm, char* options ATTRIBUTE_UNUSED, void* reserved ATTRIBUTE_UNUSED) {
+  if (vm->GetEnv(reinterpret_cast<void**>(&jvmti_env), kArtTiVersion) != 0) {
+    printf("Unable to get jvmti env!\n");
+    return 1;
+  }
+
+  CheckJvmtiError(jvmti_env, jvmti_env->AddCapabilities(&limited_caps));
+  return 0;
+}
+
+}  // namespace Test993BreakpointsNonDebuggable
+}  // namespace art
diff --git a/test/993-breakpoints-non-debuggable/onload.h b/test/993-breakpoints-non-debuggable/onload.h
new file mode 100644
index 0000000..99ce0d2b
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/onload.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_TEST_993_BREAKPOINTS_NON_DEBUGGABLE_ONLOAD_H_
+#define ART_TEST_993_BREAKPOINTS_NON_DEBUGGABLE_ONLOAD_H_
+
+#include "jni.h"
+
+namespace art {
+namespace Test993BreakpointsNonDebuggable {
+
+jint OnLoad(JavaVM* vm, char* options, void* reserved);
+
+}  // namespace Test993BreakpointsNonDebuggable
+}  // namespace art
+
+#endif  // ART_TEST_993_BREAKPOINTS_NON_DEBUGGABLE_ONLOAD_H_
diff --git a/test/993-breakpoints-non-debuggable/src/Main.java b/test/993-breakpoints-non-debuggable/src/Main.java
new file mode 100644
index 0000000..32fca46
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/src/Main.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+    public static void main(String[] args) throws Exception {
+        System.loadLibrary(args[0]);
+        art.Test993AttachAgent.loadAgent();
+        art.Test993.run(true);
+    }
+}
diff --git a/test/993-breakpoints-non-debuggable/src/art/Breakpoint.java b/test/993-breakpoints-non-debuggable/src/art/Breakpoint.java
new file mode 120000
index 0000000..3673916
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/src/art/Breakpoint.java
@@ -0,0 +1 @@
+../../../jvmti-common/Breakpoint.java
\ No newline at end of file
diff --git a/test/993-breakpoints-non-debuggable/src/art/Test993.java b/test/993-breakpoints-non-debuggable/src/art/Test993.java
new file mode 120000
index 0000000..7466288
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/src/art/Test993.java
@@ -0,0 +1 @@
+../../../993-breakpoints/src/art/Test993.java
\ No newline at end of file
diff --git a/test/993-breakpoints-non-debuggable/src/art/Test993AttachAgent.java b/test/993-breakpoints-non-debuggable/src/art/Test993AttachAgent.java
new file mode 100644
index 0000000..ac82c84
--- /dev/null
+++ b/test/993-breakpoints-non-debuggable/src/art/Test993AttachAgent.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+public class Test993AttachAgent {
+    public static native void setupJvmti();
+
+    public static void loadAgent() throws Exception {
+      setupJvmti();
+    }
+}
diff --git a/test/Android.bp b/test/Android.bp
index 4976c01..bfdba13 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -684,6 +684,7 @@
         "991-field-trace-2/field_trace.cc",
         "992-source-data/source_file.cc",
         "993-breakpoints/breakpoints.cc",
+        "993-breakpoints-non-debuggable/onload.cc",
         "996-breakpoint-obsolete/obsolete_breakpoints.cc",
         "1900-track-alloc/alloc.cc",
         "1901-get-bytecodes/bytecodes.cc",
@@ -750,6 +751,7 @@
         "936-search-onload/search_onload.cc",
         "980-redefine-object/redef_object.cc",
         "983-source-transform-verify/source_transform_art.cc",
+        "993-breakpoints-non-debuggable/native_attach_agent.cc",
         // "1952-pop-frame-jit/pop_frame.cc",
         "1959-redefine-object-instrument/fake_redef_object.cc",
         "1960-obsolete-jit-multithread-native/native_say_hi.cc",
@@ -946,6 +948,7 @@
         "800-smali/jni.cc",
         "817-hiddenapi/test_native.cc",
         "909-attach-agent/disallow_debugging.cc",
+        "993-breakpoints-non-debuggable/native_attach_agent.cc",
         "1001-app-image-regions/app_image_regions.cc",
         "1002-notify-startup/startup_interface.cc",
         "1947-breakpoint-redefine-deopt/check_deopt.cc",
@@ -1050,6 +1053,7 @@
         "992-source-data/src/art/Test992.java",
         "992-source-data/src/art/Target2.java",
         "993-breakpoints/src/art/Test993.java",
+        "993-breakpoints-non-debuggable/src/art/Test993AttachAgent.java",
         "994-breakpoint-line/src/art/Test994.java",
         "995-breakpoints-throw/src/art/Test995.java",
         "996-breakpoint-obsolete/src/art/Test996.java",
@@ -1198,6 +1202,7 @@
         "992-source-data/expected-stdout.txt",
         // Need to avoid using hidden-apis
         "993-breakpoints/expected_cts.txt",
+        "993-breakpoints-non-debuggable/expected_cts.txt",
         "994-breakpoint-line/expected-stdout.txt",
         "995-breakpoints-throw/expected-stdout.txt",
         "996-breakpoint-obsolete/expected-stdout.txt",
diff --git a/test/knownfailures.json b/test/knownfailures.json
index 984f3fc..0ea8387 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -1073,6 +1073,7 @@
           "988-method-trace",
           "989-method-trace-throw",
           "993-breakpoints",
+          "993-breakpoints-non-debuggable",
           "1002-notify-startup",
           "1003-metadata-section-strings",
           "1336-short-finalizer-timeout",
diff --git a/test/ti-agent/common_load.cc b/test/ti-agent/common_load.cc
index cc83ad3..ff8b3a8 100644
--- a/test/ti-agent/common_load.cc
+++ b/test/ti-agent/common_load.cc
@@ -29,6 +29,7 @@
 #include "909-attach-agent/attach.h"
 #include "936-search-onload/search_onload.h"
 #include "1919-vminit-thread-start-timing/vminit.h"
+#include "993-breakpoints-non-debuggable/onload.h"
 
 namespace art {
 
@@ -82,6 +83,7 @@
   { "939-hello-transformation-bcp", common_redefine::OnLoad, nullptr },
   { "941-recursive-obsolete-jit", common_redefine::OnLoad, nullptr },
   { "943-private-recursive-jit", common_redefine::OnLoad, nullptr },
+  { "993-non-debuggable", nullptr, Test993BreakpointsNonDebuggable::OnLoad },
   { "1919-vminit-thread-start-timing", Test1919VMInitThreadStart::OnLoad, nullptr },
   { "2031-zygote-compiled-frame-deopt", nullptr, MinimalOnLoad },
   { "2039-load-transform-larger", common_retransform::OnLoad, nullptr },
diff --git a/test/utils/regen-test-files b/test/utils/regen-test-files
index b2f2f16..5d900e8 100755
--- a/test/utils/regen-test-files
+++ b/test/utils/regen-test-files
@@ -205,6 +205,8 @@
   "832-cha-recursive",
   # 837-deopt: Dependency on `libarttest`.
   "837-deopt",
+  # 993-breakpoints-non-debuggable: This test needs native code.
+  "993-breakpoints-non-debuggable",
 ])
 
 known_failing_on_hwasan_tests = frozenset([