xref: /aosp_15_r20/art/runtime/debugger.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2008 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_DEBUGGER_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_DEBUGGER_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <pthread.h>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include <set>
23*795d594fSAndroid Build Coastguard Worker #include <string>
24*795d594fSAndroid Build Coastguard Worker #include <vector>
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker #include "art_method.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/array_ref.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/locks.h"
29*795d594fSAndroid Build Coastguard Worker #include "base/logging.h"
30*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
31*795d594fSAndroid Build Coastguard Worker #include "jni.h"
32*795d594fSAndroid Build Coastguard Worker #include "runtime.h"
33*795d594fSAndroid Build Coastguard Worker #include "runtime_callbacks.h"
34*795d594fSAndroid Build Coastguard Worker #include "thread.h"
35*795d594fSAndroid Build Coastguard Worker #include "thread_state.h"
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker class Dbg {
40*795d594fSAndroid Build Coastguard Worker  public:
41*795d594fSAndroid Build Coastguard Worker   EXPORT static void SetJdwpAllowed(bool allowed);
42*795d594fSAndroid Build Coastguard Worker   EXPORT static bool IsJdwpAllowed();
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker   // Invoked by the GC in case we need to keep DDMS informed.
45*795d594fSAndroid Build Coastguard Worker   static void GcDidFinish() REQUIRES(!Locks::mutator_lock_);
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker   static uint8_t ToJdwpThreadStatus(ThreadState state);
48*795d594fSAndroid Build Coastguard Worker 
49*795d594fSAndroid Build Coastguard Worker   // Indicates whether we need to force the use of interpreter when returning from the
50*795d594fSAndroid Build Coastguard Worker   // interpreter into the runtime. This allows to deoptimize the stack and continue
51*795d594fSAndroid Build Coastguard Worker   // execution with interpreter for debugging.
IsForcedInterpreterNeededForUpcall(Thread * thread,ArtMethod * m)52*795d594fSAndroid Build Coastguard Worker   static bool IsForcedInterpreterNeededForUpcall(Thread* thread, ArtMethod* m)
53*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
54*795d594fSAndroid Build Coastguard Worker     if (LIKELY(!thread->HasDebuggerShadowFrames())) {
55*795d594fSAndroid Build Coastguard Worker       return false;
56*795d594fSAndroid Build Coastguard Worker     }
57*795d594fSAndroid Build Coastguard Worker     // If we have debugger stack frames we always need to go back to interpreter unless we are
58*795d594fSAndroid Build Coastguard Worker     // native or a proxy.
59*795d594fSAndroid Build Coastguard Worker     return m != nullptr && !m->IsProxyMethod() && !m->IsNative();
60*795d594fSAndroid Build Coastguard Worker   }
61*795d594fSAndroid Build Coastguard Worker 
62*795d594fSAndroid Build Coastguard Worker   // Indicates whether we need to force the use of interpreter when handling an
63*795d594fSAndroid Build Coastguard Worker   // exception. This allows to deoptimize the stack and continue execution with
64*795d594fSAndroid Build Coastguard Worker   // the interpreter.
65*795d594fSAndroid Build Coastguard Worker   // Note: the interpreter will start by handling the exception when executing
66*795d594fSAndroid Build Coastguard Worker   // the deoptimized frames.
IsForcedInterpreterNeededForException(Thread * thread)67*795d594fSAndroid Build Coastguard Worker   static bool IsForcedInterpreterNeededForException(Thread* thread)
68*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
69*795d594fSAndroid Build Coastguard Worker     // A quick check to avoid walking the stack. If there are no shadow frames or no method
70*795d594fSAndroid Build Coastguard Worker     // that needs to be deoptimized we can safely continue with optimized code.
71*795d594fSAndroid Build Coastguard Worker     if (LIKELY(!thread->HasDebuggerShadowFrames() &&
72*795d594fSAndroid Build Coastguard Worker                Runtime::Current()->GetInstrumentation()->IsDeoptimizedMethodsEmpty())) {
73*795d594fSAndroid Build Coastguard Worker       return false;
74*795d594fSAndroid Build Coastguard Worker     }
75*795d594fSAndroid Build Coastguard Worker     return IsForcedInterpreterNeededForExceptionImpl(thread);
76*795d594fSAndroid Build Coastguard Worker   }
77*795d594fSAndroid Build Coastguard Worker 
78*795d594fSAndroid Build Coastguard Worker 
79*795d594fSAndroid Build Coastguard Worker   /*
80*795d594fSAndroid Build Coastguard Worker    * DDM support.
81*795d594fSAndroid Build Coastguard Worker    */
82*795d594fSAndroid Build Coastguard Worker   static void DdmSendThreadNotification(Thread* t, uint32_t type)
83*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
84*795d594fSAndroid Build Coastguard Worker   static void DdmSetThreadNotification(bool enable)
85*795d594fSAndroid Build Coastguard Worker       REQUIRES(!Locks::thread_list_lock_);
86*795d594fSAndroid Build Coastguard Worker   EXPORT static bool DdmHandleChunk(JNIEnv* env,
87*795d594fSAndroid Build Coastguard Worker                                     uint32_t type,
88*795d594fSAndroid Build Coastguard Worker                                     const ArrayRef<const jbyte>& data,
89*795d594fSAndroid Build Coastguard Worker                                     /*out*/ uint32_t* out_type,
90*795d594fSAndroid Build Coastguard Worker                                     /*out*/ std::vector<uint8_t>* out_data);
91*795d594fSAndroid Build Coastguard Worker 
92*795d594fSAndroid Build Coastguard Worker   EXPORT static void DdmConnected() REQUIRES_SHARED(Locks::mutator_lock_);
93*795d594fSAndroid Build Coastguard Worker   EXPORT static void DdmDisconnected() REQUIRES_SHARED(Locks::mutator_lock_);
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker   /*
96*795d594fSAndroid Build Coastguard Worker    * Allocation tracking support.
97*795d594fSAndroid Build Coastguard Worker    */
98*795d594fSAndroid Build Coastguard Worker   static void SetAllocTrackingEnabled(bool enabled) REQUIRES(!Locks::alloc_tracker_lock_);
99*795d594fSAndroid Build Coastguard Worker   static jbyteArray GetRecentAllocations()
100*795d594fSAndroid Build Coastguard Worker       REQUIRES(!Locks::alloc_tracker_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
101*795d594fSAndroid Build Coastguard Worker   static void DumpRecentAllocations() REQUIRES(!Locks::alloc_tracker_lock_);
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker   enum HpifWhen {
104*795d594fSAndroid Build Coastguard Worker     HPIF_WHEN_NEVER = 0,
105*795d594fSAndroid Build Coastguard Worker     HPIF_WHEN_NOW = 1,
106*795d594fSAndroid Build Coastguard Worker     HPIF_WHEN_NEXT_GC = 2,
107*795d594fSAndroid Build Coastguard Worker     HPIF_WHEN_EVERY_GC = 3
108*795d594fSAndroid Build Coastguard Worker   };
109*795d594fSAndroid Build Coastguard Worker   static int DdmHandleHpifChunk(HpifWhen when)
110*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
111*795d594fSAndroid Build Coastguard Worker 
112*795d594fSAndroid Build Coastguard Worker   enum HpsgWhen {
113*795d594fSAndroid Build Coastguard Worker     HPSG_WHEN_NEVER = 0,
114*795d594fSAndroid Build Coastguard Worker     HPSG_WHEN_EVERY_GC = 1,
115*795d594fSAndroid Build Coastguard Worker   };
116*795d594fSAndroid Build Coastguard Worker   enum HpsgWhat {
117*795d594fSAndroid Build Coastguard Worker     HPSG_WHAT_MERGED_OBJECTS = 0,
118*795d594fSAndroid Build Coastguard Worker     HPSG_WHAT_DISTINCT_OBJECTS = 1,
119*795d594fSAndroid Build Coastguard Worker   };
120*795d594fSAndroid Build Coastguard Worker   static bool DdmHandleHpsgNhsgChunk(HpsgWhen when, HpsgWhat what, bool native);
121*795d594fSAndroid Build Coastguard Worker 
122*795d594fSAndroid Build Coastguard Worker   static void DdmSendHeapInfo(HpifWhen reason)
123*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
124*795d594fSAndroid Build Coastguard Worker   static void DdmSendHeapSegments(bool native)
125*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
126*795d594fSAndroid Build Coastguard Worker 
GetThreadLifecycleCallback()127*795d594fSAndroid Build Coastguard Worker   static ThreadLifecycleCallback* GetThreadLifecycleCallback() {
128*795d594fSAndroid Build Coastguard Worker     return &thread_lifecycle_callback_;
129*795d594fSAndroid Build Coastguard Worker   }
130*795d594fSAndroid Build Coastguard Worker 
131*795d594fSAndroid Build Coastguard Worker  private:
132*795d594fSAndroid Build Coastguard Worker   static void DdmBroadcast(bool connect) REQUIRES_SHARED(Locks::mutator_lock_);
133*795d594fSAndroid Build Coastguard Worker 
134*795d594fSAndroid Build Coastguard Worker   static void PostThreadStart(Thread* t)
135*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
136*795d594fSAndroid Build Coastguard Worker   static void PostThreadDeath(Thread* t)
137*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
138*795d594fSAndroid Build Coastguard Worker   static void PostThreadStartOrStop(Thread*, uint32_t)
139*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker   static bool IsForcedInterpreterNeededForExceptionImpl(Thread* thread)
142*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
143*795d594fSAndroid Build Coastguard Worker 
144*795d594fSAndroid Build Coastguard Worker   class DbgThreadLifecycleCallback : public ThreadLifecycleCallback {
145*795d594fSAndroid Build Coastguard Worker    public:
146*795d594fSAndroid Build Coastguard Worker     void ThreadStart(Thread* self) override REQUIRES_SHARED(Locks::mutator_lock_);
147*795d594fSAndroid Build Coastguard Worker     void ThreadDeath(Thread* self) override REQUIRES_SHARED(Locks::mutator_lock_);
148*795d594fSAndroid Build Coastguard Worker   };
149*795d594fSAndroid Build Coastguard Worker 
150*795d594fSAndroid Build Coastguard Worker   static DbgThreadLifecycleCallback thread_lifecycle_callback_;
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(Dbg);
153*795d594fSAndroid Build Coastguard Worker };
154*795d594fSAndroid Build Coastguard Worker 
155*795d594fSAndroid Build Coastguard Worker #define CHUNK_TYPE(_name) \
156*795d594fSAndroid Build Coastguard Worker     static_cast<uint32_t>((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
157*795d594fSAndroid Build Coastguard Worker 
158*795d594fSAndroid Build Coastguard Worker }  // namespace art
159*795d594fSAndroid Build Coastguard Worker 
160*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_DEBUGGER_H_
161