• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 /*
18  * Dalvik-specific side of debugger support.  (The JDWP code is intended to
19  * be relatively generic.)
20  */
21 #ifndef ART_RUNTIME_DEBUGGER_H_
22 #define ART_RUNTIME_DEBUGGER_H_
23 
24 #include <pthread.h>
25 
26 #include <set>
27 #include <string>
28 #include <vector>
29 
30 #include "base/array_ref.h"
31 #include "class_linker.h"
32 #include "gc_root.h"
33 #include "handle.h"
34 #include "jdwp/jdwp.h"
35 #include "jni.h"
36 #include "jvalue.h"
37 #include "obj_ptr.h"
38 #include "runtime_callbacks.h"
39 #include "thread.h"
40 #include "thread_state.h"
41 
42 namespace art {
43 namespace mirror {
44 class Class;
45 class Object;
46 class Throwable;
47 }  // namespace mirror
48 class ArtField;
49 class ArtMethod;
50 class ObjectRegistry;
51 class ScopedObjectAccess;
52 class ScopedObjectAccessUnchecked;
53 class StackVisitor;
54 class Thread;
55 
56 struct DebuggerActiveMethodInspectionCallback : public MethodInspectionCallback {
57   bool IsMethodBeingInspected(ArtMethod* method) override REQUIRES_SHARED(Locks::mutator_lock_);
58   bool IsMethodSafeToJit(ArtMethod* method) override REQUIRES_SHARED(Locks::mutator_lock_);
59   bool MethodNeedsDebugVersion(ArtMethod* method) override REQUIRES_SHARED(Locks::mutator_lock_);
60 };
61 
62 struct DebuggerDdmCallback : public DdmCallback {
63   void DdmPublishChunk(uint32_t type, const ArrayRef<const uint8_t>& data)
64       override REQUIRES_SHARED(Locks::mutator_lock_);
65 };
66 
67 struct InternalDebuggerControlCallback : public DebuggerControlCallback {
68   void StartDebugger() override;
69   void StopDebugger() override;
70   bool IsDebuggerConfigured() override;
71 };
72 
73 /*
74  * Invoke-during-breakpoint support.
75  */
76 struct DebugInvokeReq {
DebugInvokeReqDebugInvokeReq77   DebugInvokeReq(uint32_t invoke_request_id,
78                  JDWP::ObjectId invoke_thread_id,
79                  ObjPtr<mirror::Object> invoke_receiver,
80                  ObjPtr<mirror::Class> invoke_class,
81                  ArtMethod* invoke_method,
82                  uint32_t invoke_options,
83                  uint64_t args[],
84                  uint32_t args_count)
85       : request_id(invoke_request_id),
86         thread_id(invoke_thread_id),
87         receiver(invoke_receiver),
88         klass(invoke_class),
89         method(invoke_method),
90         arg_count(args_count),
91         arg_values(args),
92         options(invoke_options),
93         reply(JDWP::expandBufAlloc()) {
94   }
95 
~DebugInvokeReqDebugInvokeReq96   ~DebugInvokeReq() {
97     JDWP::expandBufFree(reply);
98   }
99 
100   // Request
101   const uint32_t request_id;
102   const JDWP::ObjectId thread_id;
103   GcRoot<mirror::Object> receiver;      // not used for ClassType.InvokeMethod.
104   GcRoot<mirror::Class> klass;
105   ArtMethod* const method;
106   const uint32_t arg_count;
107   std::unique_ptr<uint64_t[]> arg_values;   // will be null if arg_count_ == 0. We take ownership
108                                             // of this array so we must delete it upon destruction.
109   const uint32_t options;
110 
111   // Reply
112   JDWP::ExpandBuf* const reply;
113 
114   void VisitRoots(RootVisitor* visitor, const RootInfo& root_info)
115       REQUIRES_SHARED(Locks::mutator_lock_);
116 
117  private:
118   DISALLOW_COPY_AND_ASSIGN(DebugInvokeReq);
119 };
120 
121 // Thread local data-structure that holds fields for controlling single-stepping.
122 class SingleStepControl {
123  public:
SingleStepControl(JDWP::JdwpStepSize step_size,JDWP::JdwpStepDepth step_depth,int stack_depth,ArtMethod * method)124   SingleStepControl(JDWP::JdwpStepSize step_size, JDWP::JdwpStepDepth step_depth,
125                     int stack_depth, ArtMethod* method)
126       : step_size_(step_size), step_depth_(step_depth),
127         stack_depth_(stack_depth), method_(method) {
128   }
129 
GetStepSize()130   JDWP::JdwpStepSize GetStepSize() const {
131     return step_size_;
132   }
133 
GetStepDepth()134   JDWP::JdwpStepDepth GetStepDepth() const {
135     return step_depth_;
136   }
137 
GetStackDepth()138   int GetStackDepth() const {
139     return stack_depth_;
140   }
141 
GetMethod()142   ArtMethod* GetMethod() const {
143     return method_;
144   }
145 
GetDexPcs()146   const std::set<uint32_t>& GetDexPcs() const {
147     return dex_pcs_;
148   }
149 
150   void AddDexPc(uint32_t dex_pc);
151 
152   bool ContainsDexPc(uint32_t dex_pc) const;
153 
154  private:
155   // See JdwpStepSize and JdwpStepDepth for details.
156   const JDWP::JdwpStepSize step_size_;
157   const JDWP::JdwpStepDepth step_depth_;
158 
159   // The stack depth when this single-step was initiated. This is used to support SD_OVER and SD_OUT
160   // single-step depth.
161   const int stack_depth_;
162 
163   // The location this single-step was initiated from.
164   // A single-step is initiated in a suspended thread. We save here the current method and the
165   // set of DEX pcs associated to the source line number where the suspension occurred.
166   // This is used to support SD_INTO and SD_OVER single-step depths so we detect when a single-step
167   // causes the execution of an instruction in a different method or at a different line number.
168   ArtMethod* method_;
169 
170   std::set<uint32_t> dex_pcs_;
171 
172   DISALLOW_COPY_AND_ASSIGN(SingleStepControl);
173 };
174 
175 // TODO rename to InstrumentationRequest.
176 class DeoptimizationRequest {
177  public:
178   enum Kind {
179     kNothing,                   // no action.
180     kRegisterForEvent,          // start listening for instrumentation event.
181     kUnregisterForEvent,        // stop listening for instrumentation event.
182     kFullDeoptimization,        // deoptimize everything.
183     kFullUndeoptimization,      // undeoptimize everything.
184     kSelectiveDeoptimization,   // deoptimize one method.
185     kSelectiveUndeoptimization  // undeoptimize one method.
186   };
187 
DeoptimizationRequest()188   DeoptimizationRequest() : kind_(kNothing), instrumentation_event_(0), method_(nullptr) {}
189 
190   DeoptimizationRequest(const DeoptimizationRequest& other)
REQUIRES_SHARED(Locks::mutator_lock_)191       REQUIRES_SHARED(Locks::mutator_lock_)
192       : kind_(other.kind_), instrumentation_event_(other.instrumentation_event_) {
193     // Create a new JNI global reference for the method.
194     SetMethod(other.Method());
195   }
196 
197   ArtMethod* Method() const REQUIRES_SHARED(Locks::mutator_lock_);
198 
199   void SetMethod(ArtMethod* m) REQUIRES_SHARED(Locks::mutator_lock_);
200 
201   // Name 'Kind()' would collide with the above enum name.
GetKind()202   Kind GetKind() const {
203     return kind_;
204   }
205 
SetKind(Kind kind)206   void SetKind(Kind kind) {
207     kind_ = kind;
208   }
209 
InstrumentationEvent()210   uint32_t InstrumentationEvent() const {
211     return instrumentation_event_;
212   }
213 
SetInstrumentationEvent(uint32_t instrumentation_event)214   void SetInstrumentationEvent(uint32_t instrumentation_event) {
215     instrumentation_event_ = instrumentation_event;
216   }
217 
218  private:
219   Kind kind_;
220 
221   // TODO we could use a union to hold the instrumentation_event and the method since they
222   // respectively have sense only for kRegisterForEvent/kUnregisterForEvent and
223   // kSelectiveDeoptimization/kSelectiveUndeoptimization.
224 
225   // Event to start or stop listening to. Only for kRegisterForEvent and kUnregisterForEvent.
226   uint32_t instrumentation_event_;
227 
228   // Method for selective deoptimization.
229   jmethodID method_;
230 };
231 std::ostream& operator<<(std::ostream& os, const DeoptimizationRequest::Kind& rhs);
232 
233 class Dbg {
234  public:
235   static void SetJdwpAllowed(bool allowed);
236   static bool IsJdwpAllowed();
237 
238   static void StartJdwp();
239   static void StopJdwp();
240 
241   // Invoked by the GC in case we need to keep DDMS informed.
242   static void GcDidFinish() REQUIRES(!Locks::mutator_lock_);
243 
244   // Return the DebugInvokeReq for the current thread.
245   static DebugInvokeReq* GetInvokeReq();
246 
247   static Thread* GetDebugThread();
248   static void ClearWaitForEventThread();
249 
250   /*
251    * Enable/disable breakpoints and step modes.  Used to provide a heads-up
252    * when the debugger attaches.
253    */
254   static void Connected();
255   static void GoActive()
256       REQUIRES(!Locks::breakpoint_lock_, !Locks::deoptimization_lock_, !Locks::mutator_lock_);
257   static void Disconnected() REQUIRES(!Locks::deoptimization_lock_, !Locks::mutator_lock_);
Dispose()258   static void Dispose() {
259     gDisposed = true;
260   }
261 
262   // Returns true if we're actually debugging with a real debugger, false if it's
263   // just DDMS (or nothing at all).
IsDebuggerActive()264   static bool IsDebuggerActive() {
265     return gDebuggerActive;
266   }
267 
268   // Configures JDWP with parsed command-line options.
269   static void ConfigureJdwp(const JDWP::JdwpOptions& jdwp_options)
270       REQUIRES_SHARED(Locks::mutator_lock_);
271 
272   // Returns true if we had -Xrunjdwp or -agentlib:jdwp= on the command line.
273   static bool IsJdwpConfigured();
274 
275   // Returns true if a method has any breakpoints.
276   static bool MethodHasAnyBreakpoints(ArtMethod* method)
277       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::breakpoint_lock_);
278 
IsDisposed()279   static bool IsDisposed() {
280     return gDisposed;
281   }
282 
283   /*
284    * Time, in milliseconds, since the last debugger activity.  Does not
285    * include DDMS activity.  Returns -1 if there has been no activity.
286    * Returns 0 if we're in the middle of handling a debugger request.
287    */
288   static int64_t LastDebuggerActivity();
289 
290   static void UndoDebuggerSuspensions()
291       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
292 
293   /*
294    * Class, Object, Array
295    */
296   static std::string GetClassName(JDWP::RefTypeId id)
297       REQUIRES_SHARED(Locks::mutator_lock_);
298   static std::string GetClassName(ObjPtr<mirror::Class> klass)
299       REQUIRES_SHARED(Locks::mutator_lock_);
300   static JDWP::JdwpError GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId* class_object_id)
301       REQUIRES_SHARED(Locks::mutator_lock_);
302   static JDWP::JdwpError GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId* superclass_id)
303       REQUIRES_SHARED(Locks::mutator_lock_);
304   static JDWP::JdwpError GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
305       REQUIRES_SHARED(Locks::mutator_lock_);
306   static JDWP::JdwpError GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
307       REQUIRES_SHARED(Locks::mutator_lock_);
308   static JDWP::JdwpError GetReflectedType(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply)
309       REQUIRES_SHARED(Locks::mutator_lock_);
310   static void GetClassList(std::vector<JDWP::RefTypeId>* classes)
311       REQUIRES_SHARED(Locks::mutator_lock_);
312   static JDWP::JdwpError GetClassInfo(JDWP::RefTypeId class_id, JDWP::JdwpTypeTag* pTypeTag,
313                                       uint32_t* pStatus, std::string* pDescriptor)
314       REQUIRES_SHARED(Locks::mutator_lock_);
315   static void FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>* ids)
316       REQUIRES_SHARED(Locks::mutator_lock_);
317   static JDWP::JdwpError GetReferenceType(JDWP::ObjectId object_id, JDWP::ExpandBuf* pReply)
318       REQUIRES_SHARED(Locks::mutator_lock_);
319   static JDWP::JdwpError GetSignature(JDWP::RefTypeId ref_type_id, std::string* signature)
320       REQUIRES_SHARED(Locks::mutator_lock_);
321   static JDWP::JdwpError GetSourceDebugExtension(JDWP::RefTypeId ref_type_id,
322                                                  std::string* extension_data)
323       REQUIRES_SHARED(Locks::mutator_lock_);
324   static JDWP::JdwpError GetSourceFile(JDWP::RefTypeId ref_type_id, std::string* source_file)
325       REQUIRES_SHARED(Locks::mutator_lock_);
326   static JDWP::JdwpError GetObjectTag(JDWP::ObjectId object_id, uint8_t* tag)
327       REQUIRES_SHARED(Locks::mutator_lock_);
328   static size_t GetTagWidth(JDWP::JdwpTag tag);
329 
330   static JDWP::JdwpError GetArrayLength(JDWP::ObjectId array_id, int32_t* length)
331       REQUIRES_SHARED(Locks::mutator_lock_);
332   static JDWP::JdwpError OutputArray(JDWP::ObjectId array_id,
333                                      int offset,
334                                      int count,
335                                      JDWP::ExpandBuf* pReply)
336       REQUIRES_SHARED(Locks::mutator_lock_);
337   static JDWP::JdwpError SetArrayElements(JDWP::ObjectId array_id, int offset, int count,
338                                           JDWP::Request* request)
339       REQUIRES_SHARED(Locks::mutator_lock_);
340 
341   static JDWP::JdwpError CreateString(const std::string& str, JDWP::ObjectId* new_string_id)
342       REQUIRES_SHARED(Locks::mutator_lock_);
343   static JDWP::JdwpError CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId* new_object_id)
344       REQUIRES_SHARED(Locks::mutator_lock_);
345   static JDWP::JdwpError CreateArrayObject(JDWP::RefTypeId array_class_id, uint32_t length,
346                                            JDWP::ObjectId* new_array_id)
347       REQUIRES_SHARED(Locks::mutator_lock_);
348 
349   //
350   // Event filtering.
351   //
352   static bool MatchThread(JDWP::ObjectId expected_thread_id, Thread* event_thread)
353       REQUIRES_SHARED(Locks::mutator_lock_);
354 
355   static bool MatchLocation(const JDWP::JdwpLocation& expected_location,
356                             const JDWP::EventLocation& event_location)
357       REQUIRES_SHARED(Locks::mutator_lock_);
358 
359   static bool MatchType(ObjPtr<mirror::Class> event_class, JDWP::RefTypeId class_id)
360       REQUIRES_SHARED(Locks::mutator_lock_);
361 
362   static bool MatchField(JDWP::RefTypeId expected_type_id, JDWP::FieldId expected_field_id,
363                          ArtField* event_field)
364       REQUIRES_SHARED(Locks::mutator_lock_);
365 
366   static bool MatchInstance(JDWP::ObjectId expected_instance_id, mirror::Object* event_instance)
367       REQUIRES_SHARED(Locks::mutator_lock_);
368 
369   //
370   // Monitors.
371   //
372   static JDWP::JdwpError GetMonitorInfo(JDWP::ObjectId object_id, JDWP::ExpandBuf* reply)
373       REQUIRES_SHARED(Locks::mutator_lock_);
374   static JDWP::JdwpError GetOwnedMonitors(JDWP::ObjectId thread_id,
375                                           std::vector<JDWP::ObjectId>* monitors,
376                                           std::vector<uint32_t>* stack_depths)
377       REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
378   static JDWP::JdwpError GetContendedMonitor(JDWP::ObjectId thread_id,
379                                              JDWP::ObjectId* contended_monitor)
380       REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
381 
382   //
383   // Heap.
384   //
385   static JDWP::JdwpError GetInstanceCounts(const std::vector<JDWP::RefTypeId>& class_ids,
386                                            std::vector<uint64_t>* counts)
387       REQUIRES_SHARED(Locks::mutator_lock_);
388   static JDWP::JdwpError GetInstances(JDWP::RefTypeId class_id, int32_t max_count,
389                                       std::vector<JDWP::ObjectId>* instances)
390       REQUIRES_SHARED(Locks::mutator_lock_);
391   static JDWP::JdwpError GetReferringObjects(JDWP::ObjectId object_id, int32_t max_count,
392                                              std::vector<JDWP::ObjectId>* referring_objects)
393       REQUIRES_SHARED(Locks::mutator_lock_);
394   static JDWP::JdwpError DisableCollection(JDWP::ObjectId object_id)
395       REQUIRES_SHARED(Locks::mutator_lock_);
396   static JDWP::JdwpError EnableCollection(JDWP::ObjectId object_id)
397       REQUIRES_SHARED(Locks::mutator_lock_);
398   static JDWP::JdwpError IsCollected(JDWP::ObjectId object_id, bool* is_collected)
399       REQUIRES_SHARED(Locks::mutator_lock_);
400   static void DisposeObject(JDWP::ObjectId object_id, uint32_t reference_count)
401       REQUIRES_SHARED(Locks::mutator_lock_);
402 
403   //
404   // Methods and fields.
405   //
406   static std::string GetMethodName(JDWP::MethodId method_id)
407       REQUIRES_SHARED(Locks::mutator_lock_);
408   static bool IsMethodObsolete(JDWP::MethodId method_id)
409       REQUIRES_SHARED(Locks::mutator_lock_);
410   static JDWP::JdwpError OutputDeclaredFields(JDWP::RefTypeId ref_type_id, bool with_generic,
411                                               JDWP::ExpandBuf* pReply)
412       REQUIRES_SHARED(Locks::mutator_lock_);
413   static JDWP::JdwpError OutputDeclaredMethods(JDWP::RefTypeId ref_type_id, bool with_generic,
414                                                JDWP::ExpandBuf* pReply)
415       REQUIRES_SHARED(Locks::mutator_lock_);
416   static JDWP::JdwpError OutputDeclaredInterfaces(JDWP::RefTypeId ref_type_id,
417                                                   JDWP::ExpandBuf* pReply)
418       REQUIRES_SHARED(Locks::mutator_lock_);
419   static void OutputLineTable(JDWP::RefTypeId ref_type_id, JDWP::MethodId method_id,
420                               JDWP::ExpandBuf* pReply)
421       REQUIRES_SHARED(Locks::mutator_lock_);
422   static void OutputVariableTable(JDWP::RefTypeId ref_type_id, JDWP::MethodId id, bool with_generic,
423                                   JDWP::ExpandBuf* pReply)
424       REQUIRES_SHARED(Locks::mutator_lock_);
425   static void OutputMethodReturnValue(JDWP::MethodId method_id, const JValue* return_value,
426                                       JDWP::ExpandBuf* pReply)
427       REQUIRES_SHARED(Locks::mutator_lock_);
428   static void OutputFieldValue(JDWP::FieldId field_id, const JValue* field_value,
429                                JDWP::ExpandBuf* pReply)
430       REQUIRES_SHARED(Locks::mutator_lock_);
431   static JDWP::JdwpError GetBytecodes(JDWP::RefTypeId class_id, JDWP::MethodId method_id,
432                                       std::vector<uint8_t>* bytecodes)
433       REQUIRES_SHARED(Locks::mutator_lock_);
434 
435   static std::string GetFieldName(JDWP::FieldId field_id)
436       REQUIRES_SHARED(Locks::mutator_lock_);
437   static JDWP::JdwpTag GetFieldBasicTag(JDWP::FieldId field_id)
438       REQUIRES_SHARED(Locks::mutator_lock_);
439   static JDWP::JdwpTag GetStaticFieldBasicTag(JDWP::FieldId field_id)
440       REQUIRES_SHARED(Locks::mutator_lock_);
441   static JDWP::JdwpError GetFieldValue(JDWP::ObjectId object_id, JDWP::FieldId field_id,
442                                        JDWP::ExpandBuf* pReply)
443       REQUIRES_SHARED(Locks::mutator_lock_);
444   static JDWP::JdwpError SetFieldValue(JDWP::ObjectId object_id, JDWP::FieldId field_id,
445                                        uint64_t value, int width)
446       REQUIRES_SHARED(Locks::mutator_lock_);
447   static JDWP::JdwpError GetStaticFieldValue(JDWP::RefTypeId ref_type_id, JDWP::FieldId field_id,
448                                              JDWP::ExpandBuf* pReply)
449       REQUIRES_SHARED(Locks::mutator_lock_);
450   static JDWP::JdwpError SetStaticFieldValue(JDWP::FieldId field_id, uint64_t value, int width)
451       REQUIRES_SHARED(Locks::mutator_lock_);
452 
453   static JDWP::JdwpError StringToUtf8(JDWP::ObjectId string_id, std::string* str)
454       REQUIRES_SHARED(Locks::mutator_lock_);
455   static void OutputJValue(JDWP::JdwpTag tag, const JValue* return_value, JDWP::ExpandBuf* pReply)
456       REQUIRES_SHARED(Locks::mutator_lock_);
457 
458   /*
459    * Thread, ThreadGroup, Frame
460    */
461   static JDWP::JdwpError GetThreadName(JDWP::ObjectId thread_id, std::string* name)
462       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::thread_list_lock_);
463   static JDWP::JdwpError GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* pReply)
464       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::thread_list_lock_);
465   static JDWP::JdwpError GetThreadGroupName(JDWP::ObjectId thread_group_id,
466                                             JDWP::ExpandBuf* pReply)
467       REQUIRES_SHARED(Locks::mutator_lock_);
468   static JDWP::JdwpError GetThreadGroupParent(JDWP::ObjectId thread_group_id,
469                                               JDWP::ExpandBuf* pReply)
470       REQUIRES_SHARED(Locks::mutator_lock_);
471   static JDWP::JdwpError GetThreadGroupChildren(JDWP::ObjectId thread_group_id,
472                                                 JDWP::ExpandBuf* pReply)
473       REQUIRES_SHARED(Locks::mutator_lock_);
474   static JDWP::ObjectId GetSystemThreadGroupId()
475       REQUIRES_SHARED(Locks::mutator_lock_);
476 
477   static JDWP::JdwpThreadStatus ToJdwpThreadStatus(ThreadState state);
478   static JDWP::JdwpError GetThreadStatus(JDWP::ObjectId thread_id,
479                                          JDWP::JdwpThreadStatus* pThreadStatus,
480                                          JDWP::JdwpSuspendStatus* pSuspendStatus)
481       REQUIRES(!Locks::thread_list_lock_);
482   static JDWP::JdwpError GetThreadDebugSuspendCount(JDWP::ObjectId thread_id,
483                                                     JDWP::ExpandBuf* pReply)
484       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
485   // static void WaitForSuspend(JDWP::ObjectId thread_id);
486 
487   // Fills 'thread_ids' with the threads in the given thread group. If thread_group_id == 0,
488   // returns all threads.
489   static void GetThreads(mirror::Object* thread_group, std::vector<JDWP::ObjectId>* thread_ids)
490       REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
491 
492   static JDWP::JdwpError GetThreadFrameCount(JDWP::ObjectId thread_id, size_t* result)
493       REQUIRES(!Locks::thread_list_lock_);
494   static JDWP::JdwpError GetThreadFrames(JDWP::ObjectId thread_id, size_t start_frame,
495                                          size_t frame_count, JDWP::ExpandBuf* buf)
496       REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
497 
498   static JDWP::ObjectId GetThreadSelfId() REQUIRES_SHARED(Locks::mutator_lock_);
499   static JDWP::ObjectId GetThreadId(Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_);
500 
501   static void SuspendVM()
502       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
503   static void ResumeVM()
504       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
505   static JDWP::JdwpError SuspendThread(JDWP::ObjectId thread_id, bool request_suspension = true)
506       REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_,
507                !Locks::thread_suspend_count_lock_);
508 
509   static void ResumeThread(JDWP::ObjectId thread_id)
510       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
511       REQUIRES_SHARED(Locks::mutator_lock_);
512   static void SuspendSelf();
513 
514   static JDWP::JdwpError GetThisObject(JDWP::ObjectId thread_id, JDWP::FrameId frame_id,
515                                        JDWP::ObjectId* result)
516       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
517       REQUIRES_SHARED(Locks::mutator_lock_);
518   static JDWP::JdwpError GetLocalValues(JDWP::Request* request, JDWP::ExpandBuf* pReply)
519       REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
520   static JDWP::JdwpError SetLocalValues(JDWP::Request* request)
521       REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
522 
523   static JDWP::JdwpError Interrupt(JDWP::ObjectId thread_id)
524       REQUIRES(!Locks::thread_list_lock_);
525 
526   /*
527    * Debugger notification
528    */
529   enum EventFlag {
530     kBreakpoint     = 0x01,
531     kSingleStep     = 0x02,
532     kMethodEntry    = 0x04,
533     kMethodExit     = 0x08,
534   };
535   static void PostFieldAccessEvent(ArtMethod* m, int dex_pc, mirror::Object* this_object,
536                                    ArtField* f)
537       REQUIRES_SHARED(Locks::mutator_lock_);
538   static void PostFieldModificationEvent(ArtMethod* m, int dex_pc,
539                                          mirror::Object* this_object, ArtField* f,
540                                          const JValue* field_value)
541       REQUIRES_SHARED(Locks::mutator_lock_);
542   static void PostException(mirror::Throwable* exception)
543       REQUIRES_SHARED(Locks::mutator_lock_);
544 
545   static void UpdateDebugger(Thread* thread, mirror::Object* this_object,
546                              ArtMethod* method, uint32_t new_dex_pc,
547                              int event_flags, const JValue* return_value)
548       REQUIRES(!Locks::breakpoint_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
549 
550   // Indicates whether we need deoptimization for debugging.
551   static bool RequiresDeoptimization();
552 
553   // Records deoptimization request in the queue.
554   static void RequestDeoptimization(const DeoptimizationRequest& req)
555       REQUIRES(!Locks::deoptimization_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
556 
557   // Manage deoptimization after updating JDWP events list. Suspends all threads, processes each
558   // request and finally resumes all threads.
559   static void ManageDeoptimization()
560       REQUIRES(!Locks::deoptimization_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
561 
562   // Breakpoints.
563   static void WatchLocation(const JDWP::JdwpLocation* pLoc, DeoptimizationRequest* req)
564       REQUIRES(!Locks::breakpoint_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
565   static void UnwatchLocation(const JDWP::JdwpLocation* pLoc, DeoptimizationRequest* req)
566       REQUIRES(!Locks::breakpoint_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
567 
568   /*
569    * Forced interpreter checkers for single-step and continue support.
570    */
571 
572   // Indicates whether we need to force the use of interpreter to invoke a method.
573   // This allows to single-step or continue into the called method.
IsForcedInterpreterNeededForCalling(Thread * thread,ArtMethod * m)574   static bool IsForcedInterpreterNeededForCalling(Thread* thread, ArtMethod* m)
575       REQUIRES_SHARED(Locks::mutator_lock_) {
576     if (!IsDebuggerActive()) {
577       return false;
578     }
579     return IsForcedInterpreterNeededForCallingImpl(thread, m);
580   }
581 
582   // Indicates whether we need to force the use of interpreter entrypoint when calling a
583   // method through the resolution trampoline. This allows to single-step or continue into
584   // the called method.
IsForcedInterpreterNeededForResolution(Thread * thread,ArtMethod * m)585   static bool IsForcedInterpreterNeededForResolution(Thread* thread, ArtMethod* m)
586       REQUIRES_SHARED(Locks::mutator_lock_) {
587     if (!IsDebuggerActive()) {
588       return false;
589     }
590     return IsForcedInterpreterNeededForResolutionImpl(thread, m);
591   }
592 
593   // Indicates whether we need to force the use of instrumentation entrypoint when calling
594   // a method through the resolution trampoline. This allows to deoptimize the stack for
595   // debugging when we returned from the called method.
IsForcedInstrumentationNeededForResolution(Thread * thread,ArtMethod * m)596   static bool IsForcedInstrumentationNeededForResolution(Thread* thread, ArtMethod* m)
597       REQUIRES_SHARED(Locks::mutator_lock_) {
598     if (!IsDebuggerActive()) {
599       return false;
600     }
601     return IsForcedInstrumentationNeededForResolutionImpl(thread, m);
602   }
603 
604   // Indicates whether we need to force the use of interpreter when returning from the
605   // interpreter into the runtime. This allows to deoptimize the stack and continue
606   // execution with interpreter for debugging.
IsForcedInterpreterNeededForUpcall(Thread * thread,ArtMethod * m)607   static bool IsForcedInterpreterNeededForUpcall(Thread* thread, ArtMethod* m)
608       REQUIRES_SHARED(Locks::mutator_lock_) {
609     if (!IsDebuggerActive() && !thread->HasDebuggerShadowFrames()) {
610       return false;
611     }
612     return IsForcedInterpreterNeededForUpcallImpl(thread, m);
613   }
614 
615   // Indicates whether we need to force the use of interpreter when handling an
616   // exception. This allows to deoptimize the stack and continue execution with
617   // the interpreter.
618   // Note: the interpreter will start by handling the exception when executing
619   // the deoptimized frames.
IsForcedInterpreterNeededForException(Thread * thread)620   static bool IsForcedInterpreterNeededForException(Thread* thread)
621       REQUIRES_SHARED(Locks::mutator_lock_) {
622     if (!IsDebuggerActive() && !thread->HasDebuggerShadowFrames()) {
623       return false;
624     }
625     return IsForcedInterpreterNeededForExceptionImpl(thread);
626   }
627 
628   // Single-stepping.
629   static JDWP::JdwpError ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize size,
630                                        JDWP::JdwpStepDepth depth)
631       REQUIRES_SHARED(Locks::mutator_lock_);
632   static void UnconfigureStep(JDWP::ObjectId thread_id)
633       REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
634 
635   /*
636    * Invoke support
637    */
638 
639   // Called by the JDWP thread to prepare invocation in the event thread (suspended on an event).
640   // If the information sent by the debugger is incorrect, it will send a reply with the
641   // appropriate error code. Otherwise, it will attach a DebugInvokeReq object to the event thread
642   // and resume it (and possibly other threads depending on the invoke options).
643   // Unlike other commands, the JDWP thread will not send the reply to the debugger (see
644   // JdwpState::ProcessRequest). The reply will be sent by the event thread itself after method
645   // invocation completes (see FinishInvokeMethod). This is required to allow the JDWP thread to
646   // process incoming commands from the debugger while the invocation is still in progress in the
647   // event thread, especially if it gets suspended by a debug event occurring in another thread.
648   static JDWP::JdwpError PrepareInvokeMethod(uint32_t request_id, JDWP::ObjectId thread_id,
649                                              JDWP::ObjectId object_id, JDWP::RefTypeId class_id,
650                                              JDWP::MethodId method_id, uint32_t arg_count,
651                                              uint64_t arg_values[], JDWP::JdwpTag* arg_types,
652                                              uint32_t options)
653       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
654       REQUIRES_SHARED(Locks::mutator_lock_);
655 
656   // Called by the event thread to execute a method prepared by the JDWP thread in the given
657   // DebugInvokeReq object. Once the invocation completes, the event thread attaches a reply
658   // to that DebugInvokeReq object so it can be sent to the debugger only when the event thread
659   // is ready to suspend (see FinishInvokeMethod).
660   static void ExecuteMethod(DebugInvokeReq* pReq);
661 
662   // Called by the event thread to send the reply of the invoke (created in ExecuteMethod)
663   // before suspending itself. This is to ensure the thread is ready to suspend before the
664   // debugger receives the reply.
665   static void FinishInvokeMethod(DebugInvokeReq* pReq);
666 
667   /*
668    * DDM support.
669    */
670   static void DdmSendThreadNotification(Thread* t, uint32_t type)
671       REQUIRES_SHARED(Locks::mutator_lock_);
672   static void DdmSetThreadNotification(bool enable)
673       REQUIRES(!Locks::thread_list_lock_);
674   static bool DdmHandleChunk(
675       JNIEnv* env,
676       uint32_t type,
677       const ArrayRef<const jbyte>& data,
678       /*out*/uint32_t* out_type,
679       /*out*/std::vector<uint8_t>* out_data);
680   static bool DdmHandlePacket(JDWP::Request* request, uint8_t** pReplyBuf, int* pReplyLen);
681   static void DdmConnected() REQUIRES_SHARED(Locks::mutator_lock_);
682   static void DdmDisconnected() REQUIRES_SHARED(Locks::mutator_lock_);
683 
684   // Visit breakpoint roots, used to prevent unloading of methods with breakpoints.
685   static void VisitRoots(RootVisitor* visitor)
686       REQUIRES_SHARED(Locks::mutator_lock_);
687 
688   /*
689    * Allocation tracking support.
690    */
691   static void SetAllocTrackingEnabled(bool enabled) REQUIRES(!Locks::alloc_tracker_lock_);
692   static jbyteArray GetRecentAllocations()
693       REQUIRES(!Locks::alloc_tracker_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
694   static void DumpRecentAllocations() REQUIRES(!Locks::alloc_tracker_lock_);
695 
696   enum HpifWhen {
697     HPIF_WHEN_NEVER = 0,
698     HPIF_WHEN_NOW = 1,
699     HPIF_WHEN_NEXT_GC = 2,
700     HPIF_WHEN_EVERY_GC = 3
701   };
702   static int DdmHandleHpifChunk(HpifWhen when)
703       REQUIRES_SHARED(Locks::mutator_lock_);
704 
705   enum HpsgWhen {
706     HPSG_WHEN_NEVER = 0,
707     HPSG_WHEN_EVERY_GC = 1,
708   };
709   enum HpsgWhat {
710     HPSG_WHAT_MERGED_OBJECTS = 0,
711     HPSG_WHAT_DISTINCT_OBJECTS = 1,
712   };
713   static bool DdmHandleHpsgNhsgChunk(HpsgWhen when, HpsgWhat what, bool native);
714 
715   static void DdmSendHeapInfo(HpifWhen reason)
716       REQUIRES_SHARED(Locks::mutator_lock_);
717   static void DdmSendHeapSegments(bool native)
718       REQUIRES_SHARED(Locks::mutator_lock_);
719 
GetObjectRegistry()720   static ObjectRegistry* GetObjectRegistry() {
721     return gRegistry;
722   }
723 
724   static JDWP::JdwpTag TagFromObject(const ScopedObjectAccessUnchecked& soa,
725                                      ObjPtr<mirror::Object> o)
726       REQUIRES_SHARED(Locks::mutator_lock_);
727 
728   static JDWP::JdwpTypeTag GetTypeTag(ObjPtr<mirror::Class> klass)
729       REQUIRES_SHARED(Locks::mutator_lock_);
730 
731   static JDWP::FieldId ToFieldId(const ArtField* f)
732       REQUIRES_SHARED(Locks::mutator_lock_);
733 
734   static void SetJdwpLocation(JDWP::JdwpLocation* location, ArtMethod* m, uint32_t dex_pc)
735       REQUIRES_SHARED(Locks::mutator_lock_)
736       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
737 
738   static JDWP::JdwpState* GetJdwpState();
739 
GetInstrumentationEvents()740   static uint32_t GetInstrumentationEvents() REQUIRES_SHARED(Locks::mutator_lock_) {
741     return instrumentation_events_;
742   }
743 
GetThreadLifecycleCallback()744   static ThreadLifecycleCallback* GetThreadLifecycleCallback() {
745     return &thread_lifecycle_callback_;
746   }
GetClassLoadCallback()747   static ClassLoadCallback* GetClassLoadCallback() {
748     return &class_load_callback_;
749   }
750 
751  private:
752   static void ExecuteMethodWithoutPendingException(ScopedObjectAccess& soa, DebugInvokeReq* pReq)
753       REQUIRES_SHARED(Locks::mutator_lock_);
754 
755   static void BuildInvokeReply(JDWP::ExpandBuf* pReply, uint32_t request_id,
756                                JDWP::JdwpTag result_tag, uint64_t result_value,
757                                JDWP::ObjectId exception)
758       REQUIRES_SHARED(Locks::mutator_lock_);
759 
760   static JDWP::JdwpError GetLocalValue(const StackVisitor& visitor,
761                                        ScopedObjectAccessUnchecked& soa, int slot,
762                                        JDWP::JdwpTag tag, uint8_t* buf, size_t width)
763       REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
764   static JDWP::JdwpError SetLocalValue(Thread* thread, StackVisitor& visitor, int slot,
765                                        JDWP::JdwpTag tag, uint64_t value, size_t width)
766       REQUIRES(!Locks::thread_list_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
767 
768   static void DdmBroadcast(bool connect) REQUIRES_SHARED(Locks::mutator_lock_);
769 
770   static void PostThreadStart(Thread* t)
771       REQUIRES_SHARED(Locks::mutator_lock_);
772   static void PostThreadDeath(Thread* t)
773       REQUIRES_SHARED(Locks::mutator_lock_);
774   static void PostThreadStartOrStop(Thread*, uint32_t)
775       REQUIRES_SHARED(Locks::mutator_lock_);
776 
777   static void PostClassPrepare(mirror::Class* c)
778       REQUIRES_SHARED(Locks::mutator_lock_);
779 
780   static void PostLocationEvent(ArtMethod* method, int pcOffset,
781                                 mirror::Object* thisPtr, int eventFlags,
782                                 const JValue* return_value)
783       REQUIRES_SHARED(Locks::mutator_lock_);
784 
785   static void ProcessDeoptimizationRequest(const DeoptimizationRequest& request)
786       REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_);
787 
788   static void RequestDeoptimizationLocked(const DeoptimizationRequest& req)
789       REQUIRES(Locks::deoptimization_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
790 
791   static bool IsForcedInterpreterNeededForCallingImpl(Thread* thread, ArtMethod* m)
792       REQUIRES_SHARED(Locks::mutator_lock_);
793 
794   static bool IsForcedInterpreterNeededForResolutionImpl(Thread* thread, ArtMethod* m)
795       REQUIRES_SHARED(Locks::mutator_lock_);
796 
797   static bool IsForcedInstrumentationNeededForResolutionImpl(Thread* thread, ArtMethod* m)
798       REQUIRES_SHARED(Locks::mutator_lock_);
799 
800   static bool IsForcedInterpreterNeededForUpcallImpl(Thread* thread, ArtMethod* m)
801       REQUIRES_SHARED(Locks::mutator_lock_);
802 
803   static bool IsForcedInterpreterNeededForExceptionImpl(Thread* thread)
804       REQUIRES_SHARED(Locks::mutator_lock_);
805 
806   // Indicates whether the debugger is making requests.
807   static bool gDebuggerActive;
808 
809   static DebuggerActiveMethodInspectionCallback gDebugActiveCallback;
810   static DebuggerDdmCallback gDebugDdmCallback;
811   static InternalDebuggerControlCallback gDebuggerControlCallback;
812 
813   // Indicates whether we should drop the JDWP connection because the runtime stops or the
814   // debugger called VirtualMachine.Dispose.
815   static bool gDisposed;
816 
817   // The registry mapping objects to JDWP ids.
818   static ObjectRegistry* gRegistry;
819 
820   // Deoptimization requests to be processed each time the event list is updated. This is used when
821   // registering and unregistering events so we do not deoptimize while holding the event list
822   // lock.
823   // TODO rename to instrumentation_requests.
824   static std::vector<DeoptimizationRequest> deoptimization_requests_ GUARDED_BY(Locks::deoptimization_lock_);
825 
826   // Count the number of events requiring full deoptimization. When the counter is > 0, everything
827   // is deoptimized, otherwise everything is undeoptimized.
828   // Note: we fully deoptimize on the first event only (when the counter is set to 1). We fully
829   // undeoptimize when the last event is unregistered (when the counter is set to 0).
830   static size_t full_deoptimization_event_count_ GUARDED_BY(Locks::deoptimization_lock_);
831 
832   static size_t* GetReferenceCounterForEvent(uint32_t instrumentation_event);
833 
834   // Instrumentation event reference counters.
835   // TODO we could use an array instead of having all these dedicated counters. Instrumentation
836   // events are bits of a mask so we could convert them to array index.
837   static size_t dex_pc_change_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
838   static size_t method_enter_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
839   static size_t method_exit_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
840   static size_t field_read_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
841   static size_t field_write_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
842   static size_t exception_catch_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
843   static uint32_t instrumentation_events_ GUARDED_BY(Locks::mutator_lock_);
844 
845   class DbgThreadLifecycleCallback : public ThreadLifecycleCallback {
846    public:
847     void ThreadStart(Thread* self) override REQUIRES_SHARED(Locks::mutator_lock_);
848     void ThreadDeath(Thread* self) override REQUIRES_SHARED(Locks::mutator_lock_);
849   };
850 
851   class DbgClassLoadCallback : public ClassLoadCallback {
852    public:
853     void ClassLoad(Handle<mirror::Class> klass) override REQUIRES_SHARED(Locks::mutator_lock_);
854     void ClassPrepare(Handle<mirror::Class> temp_klass,
855                       Handle<mirror::Class> klass) override REQUIRES_SHARED(Locks::mutator_lock_);
856   };
857 
858   static DbgThreadLifecycleCallback thread_lifecycle_callback_;
859   static DbgClassLoadCallback class_load_callback_;
860 
861   DISALLOW_COPY_AND_ASSIGN(Dbg);
862 };
863 
864 #define CHUNK_TYPE(_name) \
865     static_cast<uint32_t>((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
866 
867 }  // namespace art
868 
869 #endif  // ART_RUNTIME_DEBUGGER_H_
870