blob: 65dc13d43907c3d63edae9c86608f885feac000f [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"
Alex Light21611932017-09-26 13:07:39 -070031#include "runtime_callbacks.h"
Mingyao Yang99170c62015-07-06 11:10:37 -070032#include "thread.h"
Jeff Hao920af3e2013-08-28 15:46:38 -070033#include "thread_state.h"
Elliott Hughes872d4ec2011-10-21 17:07:15 -070034
35namespace art {
Sebastien Hertz4d25df32014-03-21 17:44:46 +010036
Elliott Hughes872d4ec2011-10-21 17:07:15 -070037class Dbg {
Elliott Hughesff17f1f2012-01-24 18:12:29 -080038 public:
Elliott Hughes4ffd3132011-10-24 12:06:42 -070039 static void SetJdwpAllowed(bool allowed);
Leonard Mosescueb842212016-10-06 17:26:36 -070040 static bool IsJdwpAllowed();
Elliott Hughes4ffd3132011-10-24 12:06:42 -070041
Elliott Hughes767a1472011-10-26 18:49:02 -070042 // Invoked by the GC in case we need to keep DDMS informed.
Mathieu Chartier90443472015-07-16 20:32:27 -070043 static void GcDidFinish() REQUIRES(!Locks::mutator_lock_);
Elliott Hughes767a1472011-10-26 18:49:02 -070044
Alex Lightfc588092020-01-23 15:39:08 -080045 static uint8_t ToJdwpThreadStatus(ThreadState state);
Daniel Mihalyieb076692014-08-22 17:33:31 +020046
47 // Indicates whether we need to force the use of interpreter when returning from the
48 // interpreter into the runtime. This allows to deoptimize the stack and continue
49 // execution with interpreter for debugging.
Mathieu Chartiere401d142015-04-22 13:56:20 -070050 static bool IsForcedInterpreterNeededForUpcall(Thread* thread, ArtMethod* m)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070051 REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lightfc588092020-01-23 15:39:08 -080052 if (LIKELY(!thread->HasDebuggerShadowFrames())) {
Daniel Mihalyieb076692014-08-22 17:33:31 +020053 return false;
54 }
Alex Lightfc588092020-01-23 15:39:08 -080055 // If we have debugger stack frames we always need to go back to interpreter unless we are
56 // native or a proxy.
57 return m != nullptr && !m->IsProxyMethod() && !m->IsNative();
Daniel Mihalyieb076692014-08-22 17:33:31 +020058 }
59
Sebastien Hertz520633b2015-09-08 17:03:36 +020060 // Indicates whether we need to force the use of interpreter when handling an
61 // exception. This allows to deoptimize the stack and continue execution with
62 // the interpreter.
63 // Note: the interpreter will start by handling the exception when executing
64 // the deoptimized frames.
65 static bool IsForcedInterpreterNeededForException(Thread* thread)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070066 REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lightfc588092020-01-23 15:39:08 -080067 if (LIKELY(!thread->HasDebuggerShadowFrames())) {
Sebastien Hertz520633b2015-09-08 17:03:36 +020068 return false;
69 }
70 return IsForcedInterpreterNeededForExceptionImpl(thread);
71 }
72
Sebastien Hertzcbc50642015-06-01 17:33:12 +020073
Elliott Hughes872d4ec2011-10-21 17:07:15 -070074 /*
75 * DDM support.
76 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -070077 static void DdmSendThreadNotification(Thread* t, uint32_t type)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070078 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertz52d131d2014-03-13 16:17:40 +010079 static void DdmSetThreadNotification(bool enable)
Mathieu Chartier90443472015-07-16 20:32:27 -070080 REQUIRES(!Locks::thread_list_lock_);
Alex Light8c2b9292017-11-09 13:21:01 -080081 static bool DdmHandleChunk(
82 JNIEnv* env,
83 uint32_t type,
84 const ArrayRef<const jbyte>& data,
85 /*out*/uint32_t* out_type,
86 /*out*/std::vector<uint8_t>* out_data);
Alex Lightfc588092020-01-23 15:39:08 -080087
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070088 static void DdmConnected() REQUIRES_SHARED(Locks::mutator_lock_);
89 static void DdmDisconnected() REQUIRES_SHARED(Locks::mutator_lock_);
Elliott Hughes767a1472011-10-26 18:49:02 -070090
Elliott Hughes545a0642011-11-08 19:10:03 -080091 /*
Man Cao8c2ff642015-05-27 17:25:30 -070092 * Allocation tracking support.
Elliott Hughes545a0642011-11-08 19:10:03 -080093 */
Mathieu Chartier90443472015-07-16 20:32:27 -070094 static void SetAllocTrackingEnabled(bool enabled) REQUIRES(!Locks::alloc_tracker_lock_);
Sebastien Hertz52d131d2014-03-13 16:17:40 +010095 static jbyteArray GetRecentAllocations()
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070096 REQUIRES(!Locks::alloc_tracker_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier90443472015-07-16 20:32:27 -070097 static void DumpRecentAllocations() REQUIRES(!Locks::alloc_tracker_lock_);
Elliott Hughes545a0642011-11-08 19:10:03 -080098
Elliott Hughes767a1472011-10-26 18:49:02 -070099 enum HpifWhen {
100 HPIF_WHEN_NEVER = 0,
101 HPIF_WHEN_NOW = 1,
102 HPIF_WHEN_NEXT_GC = 2,
103 HPIF_WHEN_EVERY_GC = 3
104 };
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700105 static int DdmHandleHpifChunk(HpifWhen when)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700106 REQUIRES_SHARED(Locks::mutator_lock_);
Elliott Hughes767a1472011-10-26 18:49:02 -0700107
108 enum HpsgWhen {
109 HPSG_WHEN_NEVER = 0,
110 HPSG_WHEN_EVERY_GC = 1,
111 };
112 enum HpsgWhat {
113 HPSG_WHAT_MERGED_OBJECTS = 0,
114 HPSG_WHAT_DISTINCT_OBJECTS = 1,
115 };
116 static bool DdmHandleHpsgNhsgChunk(HpsgWhen when, HpsgWhat what, bool native);
117
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700118 static void DdmSendHeapInfo(HpifWhen reason)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700119 REQUIRES_SHARED(Locks::mutator_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700120 static void DdmSendHeapSegments(bool native)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700121 REQUIRES_SHARED(Locks::mutator_lock_);
Elliott Hughes545a0642011-11-08 19:10:03 -0800122
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000123 static ThreadLifecycleCallback* GetThreadLifecycleCallback() {
124 return &thread_lifecycle_callback_;
125 }
126
Elliott Hughes545a0642011-11-08 19:10:03 -0800127 private:
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700128 static void DdmBroadcast(bool connect) REQUIRES_SHARED(Locks::mutator_lock_);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000129
130 static void PostThreadStart(Thread* t)
131 REQUIRES_SHARED(Locks::mutator_lock_);
132 static void PostThreadDeath(Thread* t)
133 REQUIRES_SHARED(Locks::mutator_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700134 static void PostThreadStartOrStop(Thread*, uint32_t)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700135 REQUIRES_SHARED(Locks::mutator_lock_);
Elliott Hughesa2155262011-11-16 16:26:58 -0800136
Sebastien Hertz520633b2015-09-08 17:03:36 +0200137 static bool IsForcedInterpreterNeededForExceptionImpl(Thread* thread)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700138 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertz520633b2015-09-08 17:03:36 +0200139
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000140 class DbgThreadLifecycleCallback : public ThreadLifecycleCallback {
141 public:
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100142 void ThreadStart(Thread* self) override REQUIRES_SHARED(Locks::mutator_lock_);
143 void ThreadDeath(Thread* self) override REQUIRES_SHARED(Locks::mutator_lock_);
Andreas Gampe04bbb5b2017-01-19 17:49:03 +0000144 };
145
146 static DbgThreadLifecycleCallback thread_lifecycle_callback_;
147
Ian Rogers719d1a32014-03-06 12:13:39 -0800148 DISALLOW_COPY_AND_ASSIGN(Dbg);
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700149};
150
151#define CHUNK_TYPE(_name) \
Elliott Hughes82188472011-11-07 18:11:48 -0800152 static_cast<uint32_t>((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
Elliott Hughes872d4ec2011-10-21 17:07:15 -0700153
154} // namespace art
155
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700156#endif // ART_RUNTIME_DEBUGGER_H_