Home | History | Annotate | Download | only in runtime
      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 <map>
     27 #include <set>
     28 #include <string>
     29 #include <vector>
     30 
     31 #include "gc_root.h"
     32 #include "jdwp/jdwp.h"
     33 #include "jni.h"
     34 #include "jvalue.h"
     35 #include "object_callbacks.h"
     36 #include "thread_state.h"
     37 
     38 namespace art {
     39 namespace mirror {
     40 class ArtField;
     41 class ArtMethod;
     42 class Class;
     43 class Object;
     44 class Throwable;
     45 }  // namespace mirror
     46 class AllocRecord;
     47 class ObjectRegistry;
     48 class ScopedObjectAccessUnchecked;
     49 class StackVisitor;
     50 class Thread;
     51 class ThrowLocation;
     52 
     53 /*
     54  * Invoke-during-breakpoint support.
     55  */
     56 struct DebugInvokeReq {
     57   DebugInvokeReq()
     58       : ready(false), invoke_needed(false),
     59         receiver(NULL), thread(NULL), klass(NULL), method(NULL),
     60         arg_count(0), arg_values(NULL), options(0), error(JDWP::ERR_NONE),
     61         result_tag(JDWP::JT_VOID), exception(0),
     62         lock("a DebugInvokeReq lock", kBreakpointInvokeLock),
     63         cond("a DebugInvokeReq condition variable", lock) {
     64   }
     65 
     66   /* boolean; only set when we're in the tail end of an event handler */
     67   bool ready;
     68 
     69   /* boolean; set if the JDWP thread wants this thread to do work */
     70   bool invoke_needed;
     71 
     72   /* request */
     73   mirror::Object* receiver;      /* not used for ClassType.InvokeMethod */
     74   mirror::Object* thread;
     75   mirror::Class* klass;
     76   mirror::ArtMethod* method;
     77   uint32_t arg_count;
     78   uint64_t* arg_values;   /* will be NULL if arg_count_ == 0 */
     79   uint32_t options;
     80 
     81   /* result */
     82   JDWP::JdwpError error;
     83   JDWP::JdwpTag result_tag;
     84   JValue result_value;
     85   JDWP::ObjectId exception;
     86 
     87   /* condition variable to wait on while the method executes */
     88   Mutex lock DEFAULT_MUTEX_ACQUIRED_AFTER;
     89   ConditionVariable cond GUARDED_BY(lock);
     90 
     91   void VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info)
     92       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
     93 
     94   void Clear();
     95 
     96  private:
     97   DISALLOW_COPY_AND_ASSIGN(DebugInvokeReq);
     98 };
     99 
    100 // Thread local data-structure that holds fields for controlling single-stepping.
    101 struct SingleStepControl {
    102   SingleStepControl()
    103       : is_active(false), step_size(JDWP::SS_MIN), step_depth(JDWP::SD_INTO),
    104         method(nullptr), stack_depth(0) {
    105   }
    106 
    107   // Are we single-stepping right now?
    108   bool is_active;
    109 
    110   // See JdwpStepSize and JdwpStepDepth for details.
    111   JDWP::JdwpStepSize step_size;
    112   JDWP::JdwpStepDepth step_depth;
    113 
    114   // The location this single-step was initiated from.
    115   // A single-step is initiated in a suspended thread. We save here the current method and the
    116   // set of DEX pcs associated to the source line number where the suspension occurred.
    117   // This is used to support SD_INTO and SD_OVER single-step depths so we detect when a single-step
    118   // causes the execution of an instruction in a different method or at a different line number.
    119   mirror::ArtMethod* method;
    120   std::set<uint32_t> dex_pcs;
    121 
    122   // The stack depth when this single-step was initiated. This is used to support SD_OVER and SD_OUT
    123   // single-step depth.
    124   int stack_depth;
    125 
    126   void VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info)
    127       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    128 
    129   bool ContainsDexPc(uint32_t dex_pc) const;
    130 
    131   void Clear();
    132 
    133  private:
    134   DISALLOW_COPY_AND_ASSIGN(SingleStepControl);
    135 };
    136 
    137 // TODO rename to InstrumentationRequest.
    138 class DeoptimizationRequest {
    139  public:
    140   enum Kind {
    141     kNothing,                   // no action.
    142     kRegisterForEvent,          // start listening for instrumentation event.
    143     kUnregisterForEvent,        // stop listening for instrumentation event.
    144     kFullDeoptimization,        // deoptimize everything.
    145     kFullUndeoptimization,      // undeoptimize everything.
    146     kSelectiveDeoptimization,   // deoptimize one method.
    147     kSelectiveUndeoptimization  // undeoptimize one method.
    148   };
    149 
    150   DeoptimizationRequest() : kind_(kNothing), instrumentation_event_(0), method_(nullptr) {}
    151 
    152   DeoptimizationRequest(const DeoptimizationRequest& other)
    153       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
    154       : kind_(other.kind_), instrumentation_event_(other.instrumentation_event_) {
    155     // Create a new JNI global reference for the method.
    156     SetMethod(other.Method());
    157   }
    158 
    159   mirror::ArtMethod* Method() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    160 
    161   void SetMethod(mirror::ArtMethod* m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    162 
    163   // Name 'Kind()' would collide with the above enum name.
    164   Kind GetKind() const {
    165     return kind_;
    166   }
    167 
    168   void SetKind(Kind kind) {
    169     kind_ = kind;
    170   }
    171 
    172   uint32_t InstrumentationEvent() const {
    173     return instrumentation_event_;
    174   }
    175 
    176   void SetInstrumentationEvent(uint32_t instrumentation_event) {
    177     instrumentation_event_ = instrumentation_event;
    178   }
    179 
    180  private:
    181   Kind kind_;
    182 
    183   // TODO we could use a union to hold the instrumentation_event and the method since they
    184   // respectively have sense only for kRegisterForEvent/kUnregisterForEvent and
    185   // kSelectiveDeoptimization/kSelectiveUndeoptimization.
    186 
    187   // Event to start or stop listening to. Only for kRegisterForEvent and kUnregisterForEvent.
    188   uint32_t instrumentation_event_;
    189 
    190   // Method for selective deoptimization.
    191   jmethodID method_;
    192 };
    193 
    194 class Dbg {
    195  public:
    196   class TypeCache {
    197    public:
    198     // Returns a weak global for the input type. Deduplicates.
    199     jobject Add(mirror::Class* t) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_,
    200                                                         Locks::alloc_tracker_lock_);
    201     // Clears the type cache and deletes all the weak global refs.
    202     void Clear() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_,
    203                                        Locks::alloc_tracker_lock_);
    204 
    205    private:
    206     std::multimap<int32_t, jobject> objects_;
    207   };
    208 
    209   static bool ParseJdwpOptions(const std::string& options);
    210   static void SetJdwpAllowed(bool allowed);
    211 
    212   static void StartJdwp();
    213   static void StopJdwp();
    214 
    215   // Invoked by the GC in case we need to keep DDMS informed.
    216   static void GcDidFinish() LOCKS_EXCLUDED(Locks::mutator_lock_);
    217 
    218   // Return the DebugInvokeReq for the current thread.
    219   static DebugInvokeReq* GetInvokeReq();
    220 
    221   static Thread* GetDebugThread();
    222   static void ClearWaitForEventThread();
    223 
    224   /*
    225    * Enable/disable breakpoints and step modes.  Used to provide a heads-up
    226    * when the debugger attaches.
    227    */
    228   static void Connected();
    229   static void GoActive()
    230       LOCKS_EXCLUDED(Locks::breakpoint_lock_, Locks::deoptimization_lock_, Locks::mutator_lock_);
    231   static void Disconnected() LOCKS_EXCLUDED(Locks::deoptimization_lock_, Locks::mutator_lock_);
    232   static void Disposed();
    233 
    234   // Returns true if we're actually debugging with a real debugger, false if it's
    235   // just DDMS (or nothing at all).
    236   static bool IsDebuggerActive();
    237 
    238   // Returns true if we had -Xrunjdwp or -agentlib:jdwp= on the command line.
    239   static bool IsJdwpConfigured();
    240 
    241   static bool IsDisposed();
    242 
    243   /*
    244    * Time, in milliseconds, since the last debugger activity.  Does not
    245    * include DDMS activity.  Returns -1 if there has been no activity.
    246    * Returns 0 if we're in the middle of handling a debugger request.
    247    */
    248   static int64_t LastDebuggerActivity();
    249 
    250   static void UndoDebuggerSuspensions()
    251     LOCKS_EXCLUDED(Locks::thread_list_lock_,
    252                    Locks::thread_suspend_count_lock_);
    253 
    254   /*
    255    * Class, Object, Array
    256    */
    257   static std::string GetClassName(JDWP::RefTypeId id)
    258       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    259   static std::string GetClassName(mirror::Class* klass)
    260       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    261   static JDWP::JdwpError GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& class_object_id)
    262       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    263   static JDWP::JdwpError GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclass_id)
    264       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    265   static JDWP::JdwpError GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
    266       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    267   static JDWP::JdwpError GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
    268       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    269   static JDWP::JdwpError GetReflectedType(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply)
    270       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    271   static void GetClassList(std::vector<JDWP::RefTypeId>& classes)
    272       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    273   static JDWP::JdwpError GetClassInfo(JDWP::RefTypeId class_id, JDWP::JdwpTypeTag* pTypeTag,
    274                                       uint32_t* pStatus, std::string* pDescriptor)
    275       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    276   static void FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids)
    277       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    278   static JDWP::JdwpError GetReferenceType(JDWP::ObjectId object_id, JDWP::ExpandBuf* pReply)
    279       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    280   static JDWP::JdwpError GetSignature(JDWP::RefTypeId ref_type_id, std::string* signature)
    281       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    282   static JDWP::JdwpError GetSourceFile(JDWP::RefTypeId ref_type_id, std::string& source_file)
    283       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    284   static JDWP::JdwpError GetObjectTag(JDWP::ObjectId object_id, uint8_t& tag)
    285       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    286   static size_t GetTagWidth(JDWP::JdwpTag tag);
    287 
    288   static JDWP::JdwpError GetArrayLength(JDWP::ObjectId array_id, int& length)
    289       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    290   static JDWP::JdwpError OutputArray(JDWP::ObjectId array_id, int offset, int count,
    291                                      JDWP::ExpandBuf* pReply)
    292       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    293   static JDWP::JdwpError SetArrayElements(JDWP::ObjectId array_id, int offset, int count,
    294                                           JDWP::Request& request)
    295       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    296 
    297   static JDWP::ObjectId CreateString(const std::string& str)
    298       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    299   static JDWP::JdwpError CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId& new_object)
    300       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    301   static JDWP::JdwpError CreateArrayObject(JDWP::RefTypeId array_class_id, uint32_t length,
    302                                            JDWP::ObjectId& new_array)
    303       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    304 
    305   //
    306   // Event filtering.
    307   //
    308   static bool MatchThread(JDWP::ObjectId expected_thread_id, Thread* event_thread)
    309       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    310 
    311   static bool MatchLocation(const JDWP::JdwpLocation& expected_location,
    312                             const JDWP::EventLocation& event_location)
    313       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    314 
    315   static bool MatchType(mirror::Class* event_class, JDWP::RefTypeId class_id)
    316       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    317 
    318   static bool MatchField(JDWP::RefTypeId expected_type_id, JDWP::FieldId expected_field_id,
    319                          mirror::ArtField* event_field)
    320       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    321 
    322   static bool MatchInstance(JDWP::ObjectId expected_instance_id, mirror::Object* event_instance)
    323       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    324 
    325   //
    326   // Monitors.
    327   //
    328   static JDWP::JdwpError GetMonitorInfo(JDWP::ObjectId object_id, JDWP::ExpandBuf* reply)
    329       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    330   static JDWP::JdwpError GetOwnedMonitors(JDWP::ObjectId thread_id,
    331                                           std::vector<JDWP::ObjectId>& monitors,
    332                                           std::vector<uint32_t>& stack_depths)
    333       LOCKS_EXCLUDED(Locks::thread_list_lock_)
    334       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    335   static JDWP::JdwpError GetContendedMonitor(JDWP::ObjectId thread_id,
    336                                              JDWP::ObjectId& contended_monitor)
    337       LOCKS_EXCLUDED(Locks::thread_list_lock_)
    338       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    339 
    340   //
    341   // Heap.
    342   //
    343   static JDWP::JdwpError GetInstanceCounts(const std::vector<JDWP::RefTypeId>& class_ids,
    344                                            std::vector<uint64_t>& counts)
    345       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    346   static JDWP::JdwpError GetInstances(JDWP::RefTypeId class_id, int32_t max_count,
    347                                       std::vector<JDWP::ObjectId>& instances)
    348       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    349   static JDWP::JdwpError GetReferringObjects(JDWP::ObjectId object_id, int32_t max_count,
    350                                              std::vector<JDWP::ObjectId>& referring_objects)
    351       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    352   static JDWP::JdwpError DisableCollection(JDWP::ObjectId object_id)
    353       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    354   static JDWP::JdwpError EnableCollection(JDWP::ObjectId object_id)
    355       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    356   static JDWP::JdwpError IsCollected(JDWP::ObjectId object_id, bool& is_collected)
    357       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    358   static void DisposeObject(JDWP::ObjectId object_id, uint32_t reference_count)
    359       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    360 
    361   //
    362   // Methods and fields.
    363   //
    364   static std::string GetMethodName(JDWP::MethodId method_id)
    365       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    366   static JDWP::JdwpError OutputDeclaredFields(JDWP::RefTypeId ref_type_id, bool with_generic,
    367                                               JDWP::ExpandBuf* pReply)
    368       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    369   static JDWP::JdwpError OutputDeclaredMethods(JDWP::RefTypeId ref_type_id, bool with_generic,
    370                                                JDWP::ExpandBuf* pReply)
    371       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    372   static JDWP::JdwpError OutputDeclaredInterfaces(JDWP::RefTypeId ref_type_id,
    373                                                   JDWP::ExpandBuf* pReply)
    374       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    375   static void OutputLineTable(JDWP::RefTypeId ref_type_id, JDWP::MethodId method_id,
    376                               JDWP::ExpandBuf* pReply)
    377       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    378   static void OutputVariableTable(JDWP::RefTypeId ref_type_id, JDWP::MethodId id, bool with_generic,
    379                                   JDWP::ExpandBuf* pReply)
    380       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    381   static void OutputMethodReturnValue(JDWP::MethodId method_id, const JValue* return_value,
    382                                       JDWP::ExpandBuf* pReply)
    383       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    384   static void OutputFieldValue(JDWP::FieldId field_id, const JValue* field_value,
    385                                JDWP::ExpandBuf* pReply)
    386       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    387   static JDWP::JdwpError GetBytecodes(JDWP::RefTypeId class_id, JDWP::MethodId method_id,
    388                                       std::vector<uint8_t>& bytecodes)
    389       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    390 
    391   static std::string GetFieldName(JDWP::FieldId field_id)
    392       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    393   static JDWP::JdwpTag GetFieldBasicTag(JDWP::FieldId field_id)
    394       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    395   static JDWP::JdwpTag GetStaticFieldBasicTag(JDWP::FieldId field_id)
    396       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    397   static JDWP::JdwpError GetFieldValue(JDWP::ObjectId object_id, JDWP::FieldId field_id,
    398                                        JDWP::ExpandBuf* pReply)
    399       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    400   static JDWP::JdwpError SetFieldValue(JDWP::ObjectId object_id, JDWP::FieldId field_id,
    401                                        uint64_t value, int width)
    402       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    403   static JDWP::JdwpError GetStaticFieldValue(JDWP::RefTypeId ref_type_id, JDWP::FieldId field_id,
    404                                              JDWP::ExpandBuf* pReply)
    405       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    406   static JDWP::JdwpError SetStaticFieldValue(JDWP::FieldId field_id, uint64_t value, int width)
    407       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    408 
    409   static JDWP::JdwpError StringToUtf8(JDWP::ObjectId string_id, std::string* str)
    410       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    411   static void OutputJValue(JDWP::JdwpTag tag, const JValue* return_value, JDWP::ExpandBuf* pReply)
    412       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    413 
    414   /*
    415    * Thread, ThreadGroup, Frame
    416    */
    417   static JDWP::JdwpError GetThreadName(JDWP::ObjectId thread_id, std::string& name)
    418       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
    419       LOCKS_EXCLUDED(Locks::thread_list_lock_);
    420   static JDWP::JdwpError GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* pReply)
    421       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
    422       LOCKS_EXCLUDED(Locks::thread_list_lock_);
    423   static JDWP::JdwpError GetThreadGroupName(JDWP::ObjectId thread_group_id,
    424                                             JDWP::ExpandBuf* pReply)
    425       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    426   static JDWP::JdwpError GetThreadGroupParent(JDWP::ObjectId thread_group_id,
    427                                               JDWP::ExpandBuf* pReply)
    428       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    429   static JDWP::JdwpError GetThreadGroupChildren(JDWP::ObjectId thread_group_id,
    430                                                 JDWP::ExpandBuf* pReply)
    431       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    432   static JDWP::ObjectId GetSystemThreadGroupId()
    433       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    434 
    435   static JDWP::JdwpThreadStatus ToJdwpThreadStatus(ThreadState state);
    436   static JDWP::JdwpError GetThreadStatus(JDWP::ObjectId thread_id,
    437                                          JDWP::JdwpThreadStatus* pThreadStatus,
    438                                          JDWP::JdwpSuspendStatus* pSuspendStatus)
    439       LOCKS_EXCLUDED(Locks::thread_list_lock_);
    440   static JDWP::JdwpError GetThreadDebugSuspendCount(JDWP::ObjectId thread_id,
    441                                                     JDWP::ExpandBuf* pReply)
    442       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    443                      Locks::thread_suspend_count_lock_);
    444   // static void WaitForSuspend(JDWP::ObjectId thread_id);
    445 
    446   // Fills 'thread_ids' with the threads in the given thread group. If thread_group_id == 0,
    447   // returns all threads.
    448   static void GetThreads(mirror::Object* thread_group, std::vector<JDWP::ObjectId>* thread_ids)
    449       LOCKS_EXCLUDED(Locks::thread_list_lock_)
    450       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    451 
    452   static JDWP::JdwpError GetThreadFrameCount(JDWP::ObjectId thread_id, size_t& result)
    453       LOCKS_EXCLUDED(Locks::thread_list_lock_);
    454   static JDWP::JdwpError GetThreadFrames(JDWP::ObjectId thread_id, size_t start_frame,
    455                                          size_t frame_count, JDWP::ExpandBuf* buf)
    456       LOCKS_EXCLUDED(Locks::thread_list_lock_)
    457       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    458 
    459   static JDWP::ObjectId GetThreadSelfId() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    460   static JDWP::ObjectId GetThreadId(Thread* thread) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    461 
    462   static void SuspendVM()
    463       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    464                      Locks::thread_suspend_count_lock_);
    465   static void ResumeVM()
    466       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    467                      Locks::thread_suspend_count_lock_);
    468   static JDWP::JdwpError SuspendThread(JDWP::ObjectId thread_id, bool request_suspension = true)
    469       LOCKS_EXCLUDED(Locks::mutator_lock_,
    470                      Locks::thread_list_lock_,
    471                      Locks::thread_suspend_count_lock_);
    472 
    473   static void ResumeThread(JDWP::ObjectId thread_id)
    474       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    475                      Locks::thread_suspend_count_lock_)
    476       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    477   static void SuspendSelf();
    478 
    479   static JDWP::JdwpError GetThisObject(JDWP::ObjectId thread_id, JDWP::FrameId frame_id,
    480                                        JDWP::ObjectId* result)
    481       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    482                      Locks::thread_suspend_count_lock_)
    483       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    484   static JDWP::JdwpError GetLocalValues(JDWP::Request* request, JDWP::ExpandBuf* pReply)
    485       LOCKS_EXCLUDED(Locks::thread_list_lock_)
    486       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    487   static JDWP::JdwpError SetLocalValues(JDWP::Request* request)
    488       LOCKS_EXCLUDED(Locks::thread_list_lock_)
    489       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    490 
    491   static JDWP::JdwpError Interrupt(JDWP::ObjectId thread_id)
    492       LOCKS_EXCLUDED(Locks::thread_list_lock_);
    493 
    494   /*
    495    * Debugger notification
    496    */
    497   enum {
    498     kBreakpoint     = 0x01,
    499     kSingleStep     = 0x02,
    500     kMethodEntry    = 0x04,
    501     kMethodExit     = 0x08,
    502   };
    503   static void PostFieldAccessEvent(mirror::ArtMethod* m, int dex_pc, mirror::Object* this_object,
    504                                    mirror::ArtField* f)
    505       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    506   static void PostFieldModificationEvent(mirror::ArtMethod* m, int dex_pc,
    507                                          mirror::Object* this_object, mirror::ArtField* f,
    508                                          const JValue* field_value)
    509       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    510   static void PostException(const ThrowLocation& throw_location, mirror::ArtMethod* catch_method,
    511                             uint32_t catch_dex_pc, mirror::Throwable* exception)
    512       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    513   static void PostThreadStart(Thread* t)
    514       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    515   static void PostThreadDeath(Thread* t)
    516       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    517   static void PostClassPrepare(mirror::Class* c)
    518       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    519 
    520   static void UpdateDebugger(Thread* thread, mirror::Object* this_object,
    521                              mirror::ArtMethod* method, uint32_t new_dex_pc,
    522                              int event_flags, const JValue* return_value)
    523       LOCKS_EXCLUDED(Locks::breakpoint_lock_)
    524       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    525 
    526   // Indicates whether we need deoptimization for debugging.
    527   static bool RequiresDeoptimization();
    528 
    529   // Records deoptimization request in the queue.
    530   static void RequestDeoptimization(const DeoptimizationRequest& req)
    531       LOCKS_EXCLUDED(Locks::deoptimization_lock_)
    532       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    533 
    534   // Support delayed full undeoptimization requests. This is currently only used for single-step
    535   // events.
    536   static void DelayFullUndeoptimization() LOCKS_EXCLUDED(Locks::deoptimization_lock_);
    537   static void ProcessDelayedFullUndeoptimizations()
    538       LOCKS_EXCLUDED(Locks::deoptimization_lock_)
    539       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    540 
    541   // Manage deoptimization after updating JDWP events list. Suspends all threads, processes each
    542   // request and finally resumes all threads.
    543   static void ManageDeoptimization()
    544       LOCKS_EXCLUDED(Locks::deoptimization_lock_)
    545       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    546 
    547   // Breakpoints.
    548   static void WatchLocation(const JDWP::JdwpLocation* pLoc, DeoptimizationRequest* req)
    549       LOCKS_EXCLUDED(Locks::breakpoint_lock_)
    550       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    551   static void UnwatchLocation(const JDWP::JdwpLocation* pLoc, DeoptimizationRequest* req)
    552       LOCKS_EXCLUDED(Locks::breakpoint_lock_)
    553       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    554 
    555   // Single-stepping.
    556   static JDWP::JdwpError ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize size,
    557                                        JDWP::JdwpStepDepth depth)
    558       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    559   static void UnconfigureStep(JDWP::ObjectId thread_id)
    560       LOCKS_EXCLUDED(Locks::thread_list_lock_)
    561       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    562 
    563   static JDWP::JdwpError InvokeMethod(JDWP::ObjectId thread_id, JDWP::ObjectId object_id,
    564                                       JDWP::RefTypeId class_id, JDWP::MethodId method_id,
    565                                       uint32_t arg_count, uint64_t* arg_values,
    566                                       JDWP::JdwpTag* arg_types, uint32_t options,
    567                                       JDWP::JdwpTag* pResultTag, uint64_t* pResultValue,
    568                                       JDWP::ObjectId* pExceptObj)
    569       LOCKS_EXCLUDED(Locks::thread_list_lock_,
    570                      Locks::thread_suspend_count_lock_)
    571       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    572   static void ExecuteMethod(DebugInvokeReq* pReq);
    573 
    574   /*
    575    * DDM support.
    576    */
    577   static void DdmSendThreadNotification(Thread* t, uint32_t type)
    578       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    579   static void DdmSetThreadNotification(bool enable)
    580       LOCKS_EXCLUDED(Locks::thread_list_lock_);
    581   static bool DdmHandlePacket(JDWP::Request& request, uint8_t** pReplyBuf, int* pReplyLen);
    582   static void DdmConnected() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    583   static void DdmDisconnected() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    584   static void DdmSendChunk(uint32_t type, const std::vector<uint8_t>& bytes)
    585       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    586   static void DdmSendChunk(uint32_t type, size_t len, const uint8_t* buf)
    587       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    588   static void DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count)
    589       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    590 
    591   static void VisitRoots(RootCallback* callback, void* arg)
    592       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    593 
    594   /*
    595    * Recent allocation tracking support.
    596    */
    597   static void RecordAllocation(mirror::Class* type, size_t byte_count)
    598       LOCKS_EXCLUDED(Locks::alloc_tracker_lock_)
    599       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    600   static void SetAllocTrackingEnabled(bool enabled) LOCKS_EXCLUDED(Locks::alloc_tracker_lock_);
    601   static bool IsAllocTrackingEnabled() {
    602     return recent_allocation_records_ != nullptr;
    603   }
    604   static jbyteArray GetRecentAllocations()
    605       LOCKS_EXCLUDED(Locks::alloc_tracker_lock_)
    606       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    607   static size_t HeadIndex() EXCLUSIVE_LOCKS_REQUIRED(Locks::alloc_tracker_lock_);
    608   static void DumpRecentAllocations() LOCKS_EXCLUDED(Locks::alloc_tracker_lock_);
    609 
    610   enum HpifWhen {
    611     HPIF_WHEN_NEVER = 0,
    612     HPIF_WHEN_NOW = 1,
    613     HPIF_WHEN_NEXT_GC = 2,
    614     HPIF_WHEN_EVERY_GC = 3
    615   };
    616   static int DdmHandleHpifChunk(HpifWhen when)
    617       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    618 
    619   enum HpsgWhen {
    620     HPSG_WHEN_NEVER = 0,
    621     HPSG_WHEN_EVERY_GC = 1,
    622   };
    623   enum HpsgWhat {
    624     HPSG_WHAT_MERGED_OBJECTS = 0,
    625     HPSG_WHAT_DISTINCT_OBJECTS = 1,
    626   };
    627   static bool DdmHandleHpsgNhsgChunk(HpsgWhen when, HpsgWhat what, bool native);
    628 
    629   static void DdmSendHeapInfo(HpifWhen reason)
    630       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    631   static void DdmSendHeapSegments(bool native)
    632       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    633 
    634   static ObjectRegistry* GetObjectRegistry() {
    635     return gRegistry;
    636   }
    637 
    638   static JDWP::JdwpTag TagFromObject(const ScopedObjectAccessUnchecked& soa, mirror::Object* o)
    639       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    640 
    641   static JDWP::JdwpTypeTag GetTypeTag(mirror::Class* klass)
    642       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    643 
    644   static JDWP::FieldId ToFieldId(const mirror::ArtField* f)
    645       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    646 
    647   static void SetJdwpLocation(JDWP::JdwpLocation* location, mirror::ArtMethod* m, uint32_t dex_pc)
    648       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    649 
    650  private:
    651   static JDWP::JdwpError GetLocalValue(const StackVisitor& visitor,
    652                                        ScopedObjectAccessUnchecked& soa, int slot,
    653                                        JDWP::JdwpTag tag, uint8_t* buf, size_t width)
    654       LOCKS_EXCLUDED(Locks::thread_list_lock_)
    655       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    656   static JDWP::JdwpError SetLocalValue(StackVisitor& visitor, int slot, JDWP::JdwpTag tag,
    657                                        uint64_t value, size_t width)
    658       LOCKS_EXCLUDED(Locks::thread_list_lock_)
    659       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    660 
    661   static void DdmBroadcast(bool connect) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    662   static void PostThreadStartOrStop(Thread*, uint32_t)
    663       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    664 
    665   static void PostLocationEvent(mirror::ArtMethod* method, int pcOffset,
    666                                 mirror::Object* thisPtr, int eventFlags,
    667                                 const JValue* return_value)
    668       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    669 
    670   static void ProcessDeoptimizationRequest(const DeoptimizationRequest& request)
    671       EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
    672 
    673   static void RequestDeoptimizationLocked(const DeoptimizationRequest& req)
    674       EXCLUSIVE_LOCKS_REQUIRED(Locks::deoptimization_lock_)
    675       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    676 
    677   static AllocRecord* recent_allocation_records_ PT_GUARDED_BY(Locks::alloc_tracker_lock_);
    678   static size_t alloc_record_max_ GUARDED_BY(Locks::alloc_tracker_lock_);
    679   static size_t alloc_record_head_ GUARDED_BY(Locks::alloc_tracker_lock_);
    680   static size_t alloc_record_count_ GUARDED_BY(Locks::alloc_tracker_lock_);
    681 
    682   static ObjectRegistry* gRegistry;
    683 
    684   // Deoptimization requests to be processed each time the event list is updated. This is used when
    685   // registering and unregistering events so we do not deoptimize while holding the event list
    686   // lock.
    687   // TODO rename to instrumentation_requests.
    688   static std::vector<DeoptimizationRequest> deoptimization_requests_ GUARDED_BY(Locks::deoptimization_lock_);
    689 
    690   // Count the number of events requiring full deoptimization. When the counter is > 0, everything
    691   // is deoptimized, otherwise everything is undeoptimized.
    692   // Note: we fully deoptimize on the first event only (when the counter is set to 1). We fully
    693   // undeoptimize when the last event is unregistered (when the counter is set to 0).
    694   static size_t full_deoptimization_event_count_ GUARDED_BY(Locks::deoptimization_lock_);
    695 
    696   // Count the number of full undeoptimization requests delayed to next resume or end of debug
    697   // session.
    698   static size_t delayed_full_undeoptimization_count_ GUARDED_BY(Locks::deoptimization_lock_);
    699 
    700   static size_t* GetReferenceCounterForEvent(uint32_t instrumentation_event);
    701 
    702   // Weak global type cache, TODO improve this.
    703   static TypeCache type_cache_ GUARDED_BY(Locks::alloc_tracker_lock_);
    704 
    705   // Instrumentation event reference counters.
    706   // TODO we could use an array instead of having all these dedicated counters. Instrumentation
    707   // events are bits of a mask so we could convert them to array index.
    708   static size_t dex_pc_change_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
    709   static size_t method_enter_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
    710   static size_t method_exit_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
    711   static size_t field_read_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
    712   static size_t field_write_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
    713   static size_t exception_catch_event_ref_count_ GUARDED_BY(Locks::deoptimization_lock_);
    714   static uint32_t instrumentation_events_ GUARDED_BY(Locks::mutator_lock_);
    715 
    716   friend class AllocRecord;  // For type_cache_ with proper annotalysis.
    717   DISALLOW_COPY_AND_ASSIGN(Dbg);
    718 };
    719 
    720 #define CHUNK_TYPE(_name) \
    721     static_cast<uint32_t>((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
    722 
    723 }  // namespace art
    724 
    725 #endif  // ART_RUNTIME_DEBUGGER_H_
    726