blob: a79add9b8e786bd4c010c3380a2cc7417dd33fd7 [file] [log] [blame]
Elliott Hughes872d4ec2011-10-21 17:07:15 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_DEBUGGER_H_
18#define ART_RUNTIME_DEBUGGER_H_
Elliott Hughes872d4ec2011-10-21 17:07:15 -070019
20#include <pthread.h>
21
Sebastien Hertz61b7f1b2013-11-15 15:59:30 +010022#include <set>
Elliott Hughes3bb81562011-10-21 18:52:59 -070023#include <string>
Sebastien Hertz4d25df32014-03-21 17:44:46 +010024#include <vector>
Elliott Hughes3bb81562011-10-21 18:52:59 -070025
Alex Lightfc588092020-01-23 15:39:08 -080026#include "art_method.h"
Alex Light8c2b9292017-11-09 13:21:01 -080027#include "base/array_ref.h"
Alex Lightfc588092020-01-23 15:39:08 -080028#include "base/locks.h"
29#include "base/logging.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080030#include "jni.h"
Mythri Alleab474882022-01-17 16:43:04 +000031#include "runtime.h"
Alex Light21611932017-09-26 13:07:39 -070032#include "runtime_callbacks.h"
Mingyao Yang99170c62015-07-06 11:10:37 -070033#include "thread.h"
Jeff Hao920af3e2013-08-28 15:46:38 -070034#include "thread_state.h"
Elliott Hughes872d4ec2011-10-21 17:07:15 -070035
36namespace art {
Sebastien Hertz4d25df32014-03-21 17:44:46 +010037
Elliott Hughes872d4ec2011-10-21 17:07:15 -070038class Dbg {
Elliott Hughesff17f1f2012-01-24 18:12:29 -080039 public:
Elliott Hughes4ffd3132011-10-24 12:06:42 -070040 static void SetJdwpAllowed(bool allowed);
Leonard Mosescueb842212016-10-06 17:26:36 -070041 static bool IsJdwpAllowed();
Elliott Hughes4ffd3132011-10-24 12:06:42 -070042
Elliott Hughes767a1472011-10-26 18:49:02 -070043 // Invoked by the GC in case we need to keep DDMS informed.
Mathieu Chartier90443472015-07-16 20:32:27 -070044 static void GcDidFinish() REQUIRES(!Locks::mutator_lock_);
Elliott Hughes767a1472011-10-26 18:49:02 -070045
Alex Lightfc588092020-01-23 15:39:08 -080046 static uint8_t ToJdwpThreadStatus(ThreadState state);
Daniel Mihalyieb076692014-08-22 17:33:31 +020047
48 // Indicates whether we need to force the use of interpreter when returning from the
49 // interpreter into the runtime. This allows to deoptimize the stack and continue
50 // execution with interpreter for debugging.
Mathieu Chartiere401d142015-04-22 13:56:20 -070051 static bool IsForcedInterpreterNeededForUpcall(Thread* thread, ArtMethod* m)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070052 REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lightfc588092020-01-23 15:39:08 -080053 if (LIKELY(!thread->HasDebuggerShadowFrames())) {
Daniel Mihalyieb076692014-08-22 17:33:31 +020054 return false;
55 }
Alex Lightfc588092020-01-23 15:39:08 -080056 // If we have debugger stack frames we always need to go back to interpreter unless we are
57 // native or a proxy.
58 return m != nullptr && !m->IsProxyMethod() && !m->IsNative();
Daniel Mihalyieb076692014-08-22 17:33:31 +020059 }
60
Sebastien Hertz520633b2015-09-08 17:03:36 +020061 // Indicates whether we need to force the use of interpreter when handling an
62 // exception. This allows to deoptimize the stack and continue execution with
63 // the interpreter.
64 // Note: the interpreter will start by handling the exception when executing
65 // the deoptimized frames.
66 static bool IsForcedInterpreterNeededForException(Thread* thread)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070067 REQUIRES_SHARED(Locks::mutator_lock_) {
Mythri Alleab474882022-01-17 16:43:04 +000068 // A quick check to avoid walking the stack. If there are no shadow frames or no method
69 // that needs to be deoptimized we can safely continue with optimized code.
70 if (LIKELY(!thread->HasDebuggerShadowFrames() &&
71 Runtime::Current()->GetInstrumentation()->IsDeoptimizedMethodsEmpty())) {
Sebastien Hertz520633b2015-09-08 17:03:36 +020072 return false;
73 }
74 return IsForcedInterpreterNeededForExceptionImpl(thread);
75 }
76
Sebastien Hertzcbc50642015-06-01 17:33:12 +020077
Elliott Hughes872d4ec2011-10-21 17:07:15 -070078 /*
79 * DDM support.
80 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -070081 static void DdmSendThreadNotification(Thread* t, uint32_t type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070082 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertz52d131d2014-03-13 16:17:40 +010083 static void DdmSetThreadNotification(bool enable)
Mathieu Chartier90443472015-07-16 20:32:27 -070084 REQUIRES(!Locks::thread_list_lock_);
Alex Light8c2b9292017-11-09 13:21:01 -080085 static bool DdmHandleChunk(
86 JNIEnv* env,
87 uint32_t type,
88 const ArrayRef<const jbyte>& data,
89 /*out*/uint32_t* out_type,
90 /*out*/std::vector<uint8_t>* out_data);
Alex Lightfc588092020-01-23 15:39:08 -080091
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070092 static void DdmConnected() REQUIRES_SHARED(Locks::mutator_lock_);
93 static void DdmDisconnected() REQUIRES_SHARED(Locks::mutator_lock_);
Elliott Hughes767a1472011-10-26 18:49:02 -070094
Elliott Hughes545a0642011-11-08 19:10:03 -080095 /*
Man Cao8c2ff642015-05-27 17:25:30 -070096 * Allocation tracking support.
Elliott Hughes545a0642011-11-08 19:10:03 -080097 */
Mathieu Chartier90443472015-07-16 20:32:27 -070098 static void SetAllocTrackingEnabled(bool enabled) REQUIRES(!Locks::alloc_tracker_lock_);
Sebastien Hertz52d131d2014-03-13 16:17:40 +010099 static jbyteArray GetRecentAllocations()
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700100 REQUIRES(!Locks::alloc_tracker_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier90443472015-07-16 20:32:27 -0700101 static void DumpRecentAllocations() REQUIRES(!Locks::alloc_tracker_lock_);
Elliott Hughes545a0642011-11-08 19:10:03 -0800102
Elliott Hughes767a1472011-10-26 18:49:02 -0700103 enum HpifWhen {
104 HPIF_WHEN_NEVER = 0,
105 HPIF_WHEN_NOW = 1,
106 HPIF_WHEN_NEXT_GC = 2,
107 HPIF_WHEN_EVERY_GC = 3
108 };
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700109 static int DdmHandleHpifChunk(HpifWhen when)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700110 REQUIRES_SHARED(Locks::mutator_lock_);
Elliott Hughes767a1472011-10-26 18:49:02 -0700111
112 enum HpsgWhen {
113 HPSG_WHEN_NEVER = 0,
114 HPSG_WHEN_EVERY_GC = 1,
115 };
116 enum HpsgWhat {
117 HPSG_WHAT_MERGED_OBJECTS = 0,
118 HPSG_WHAT_DISTINCT_OBJECTS = 1,
119 };
120 static bool DdmHandleHpsgNhsgChunk(HpsgWhen when, HpsgWhat what, bool native);
121
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700122 static void DdmSendHeapInfo(HpifWhen reason)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700123 REQUIRES_SHARED(Locks::mutator_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700124 static void DdmSendHeapSegments(bool native)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700125 REQUIRES_SHARED(Locks::mutator_lock_);
Elliott Hughes545a0642011-11-08 19:10:03 -0800126
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000127 static ThreadLifecycleCallback* GetThreadLifecycleCallback() {
128 return &thread_lifecycle_callback_;
129 }
130
Elliott Hughes545a0642011-11-08 19:10:03 -0800131 private:
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700132 static void DdmBroadcast(bool connect) REQUIRES_SHARED(Locks::mutator_lock_);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000133
134 static void PostThreadStart(Thread* t)
135 REQUIRES_SHARED(Locks::mutator_lock_);
136 static void PostThreadDeath(Thread* t)
137 REQUIRES_SHARED(Locks::mutator_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700138 static void PostThreadStartOrStop(Thread*, uint32_t)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700139 REQUIRES_SHARED(Locks::mutator_lock_);
Elliott Hughesa2155262011-11-16 16:26:58 -0800140
Sebastien Hertz520633b2015-09-08 17:03:36 +0200141 static bool IsForcedInterpreterNeededForExceptionImpl(Thread* thread)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700142 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertz520633b2015-09-08 17:03:36 +0200143
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000144 class DbgThreadLifecycleCallback : public ThreadLifecycleCallback {
145 public:
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100146 void ThreadStart(Thread* self) override REQUIRES_SHARED(Locks::mutator_lock_);
147 void ThreadDeath(Thread* self) override REQUIRES_SHARED(Locks::mutator_lock_);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000148 };
149
150 static DbgThreadLifecycleCallback thread_lifecycle_callback_;
151
Ian Rogers719d1a32014-03-06 12:13:39 -0800152 DISALLOW_COPY_AND_ASSIGN(Dbg);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700153};
154
155#define CHUNK_TYPE(_name) \
Elliott Hughes82188472011-11-07 18:11:48 -0800156 static_cast<uint32_t>((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700157
158} // namespace art
159
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700160#endif // ART_RUNTIME_DEBUGGER_H_