debugger.h revision 1b09b094a85e03f6ef5f687f58bb91c433273ba1
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 The Android Open Source Project
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * you may not use this file except in compliance with the License.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You may obtain a copy of the License at
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
1002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * Unless required by applicable law or agreed to in writing, software
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * See the License for the specific language governing permissions and
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * limitations under the License.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
1602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Dalvik-specific side of debugger support.  (The JDWP code is intended to
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * be relatively generic.)
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef ART_DEBUGGER_H_
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define ART_DEBUGGER_H_
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <pthread.h>
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <string>
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "jdwp/jdwp.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "object.h"
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace art {
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochstruct AllocRecord;
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)class Thread;
35591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
36591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch/*
37591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * Invoke-during-breakpoint support.
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct DebugInvokeReq {
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  DebugInvokeReq()
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      : ready(false), invoke_needed_(false),
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        receiver_(NULL), thread_(NULL), class_(NULL), method_(NULL),
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        arg_count_(0), arg_values_(NULL), options_(0), error(JDWP::ERR_NONE),
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result_tag(JDWP::JT_VOID), exception(0),
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        lock_("a DebugInvokeReq lock"),
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        cond_("a DebugInvokeReq condition variable") {
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  /* boolean; only set when we're in the tail end of an event handler */
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  bool ready;
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)  /* boolean; set if the JDWP thread wants this thread to do work */
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  bool invoke_needed_;
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  /* request */
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  Object* receiver_;      /* not used for ClassType.InvokeMethod */
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  Object* thread_;
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  Class* class_;
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  Method* method_;
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  uint32_t arg_count_;
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  uint64_t* arg_values_;   /* will be NULL if arg_count_ == 0 */
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  uint32_t options_;
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  /* result */
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  JDWP::JdwpError error;
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  JDWP::JdwpTag result_tag;
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  JValue result_value;
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  JDWP::ObjectId exception;
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  /* condition variable to wait on while the method executes */
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  Mutex lock_;
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  ConditionVariable cond_;
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Dbg {
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public:
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static bool ParseJdwpOptions(const std::string& options);
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static void SetJdwpAllowed(bool allowed);
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static void StartJdwp();
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static void StopJdwp();
8281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Invoked by the GC in case we need to keep DDMS informed.
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static void GcDidFinish() LOCKS_EXCLUDED(GlobalSynchronization::mutator_lock_);
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Return the DebugInvokeReq for the current thread.
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static DebugInvokeReq* GetInvokeReq();
8881a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
8981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)  static Thread* GetDebugThread();
9081a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)  static void ClearWaitForEventThread();
9181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
9281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)  /*
9381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)   * Enable/disable breakpoints and step modes.  Used to provide a heads-up
9481a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)   * when the debugger attaches.
9581a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)   */
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static void Connected();
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static void GoActive();
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static void Disconnected();
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static void Disposed();
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Returns true if we're actually debugging with a real debugger, false if it's
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // just DDMS (or nothing at all).
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static bool IsDebuggerActive();
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Returns true if we had -Xrunjdwp or -agentlib:jdwp= on the command line.
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static bool IsJdwpConfigured();
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static bool IsDisposed();
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  /*
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)   * Time, in milliseconds, since the last debugger activity.  Does not
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)   * include DDMS activity.  Returns -1 if there has been no activity.
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)   * Returns 0 if we're in the middle of handling a debugger request.
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)   */
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static int64_t LastDebuggerActivity();
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
117  static void UndoDebuggerSuspensions();
118
119  static void Exit(int status);
120
121  static void VisitRoots(Heap::RootVisitor* visitor, void* arg);
122
123  /*
124   * Class, Object, Array
125   */
126  static std::string GetClassName(JDWP::RefTypeId id)
127      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
128  static JDWP::JdwpError GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& classObjectId)
129      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
130  static JDWP::JdwpError GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclassId)
131      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
132  static JDWP::JdwpError GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
133      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
134  static JDWP::JdwpError GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
135      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
136  static JDWP::JdwpError GetReflectedType(JDWP::RefTypeId classId, JDWP::ExpandBuf* pReply)
137      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
138  static void GetClassList(std::vector<JDWP::RefTypeId>& classes)
139      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
140  static JDWP::JdwpError GetClassInfo(JDWP::RefTypeId classId, JDWP::JdwpTypeTag* pTypeTag,
141                                      uint32_t* pStatus, std::string* pDescriptor)
142      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
143  static void FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids)
144      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
145  static JDWP::JdwpError GetReferenceType(JDWP::ObjectId objectId, JDWP::ExpandBuf* pReply);
146  static JDWP::JdwpError GetSignature(JDWP::RefTypeId refTypeId, std::string& signature)
147      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
148  static JDWP::JdwpError GetSourceFile(JDWP::RefTypeId refTypeId, std::string& source_file)
149      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
150  static JDWP::JdwpError GetObjectTag(JDWP::ObjectId objectId, uint8_t& tag)
151      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
152  static size_t GetTagWidth(JDWP::JdwpTag tag);
153
154  static JDWP::JdwpError GetArrayLength(JDWP::ObjectId arrayId, int& length)
155      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
156  static JDWP::JdwpError OutputArray(JDWP::ObjectId arrayId, int firstIndex, int count,
157                                     JDWP::ExpandBuf* pReply)
158      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
159  static JDWP::JdwpError SetArrayElements(JDWP::ObjectId arrayId, int firstIndex, int count,
160                                          const uint8_t* buf)
161      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
162
163  static JDWP::ObjectId CreateString(const std::string& str)
164      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
165  static JDWP::JdwpError CreateObject(JDWP::RefTypeId classId, JDWP::ObjectId& new_object)
166      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
167  static JDWP::JdwpError CreateArrayObject(JDWP::RefTypeId arrayTypeId, uint32_t length,
168                                           JDWP::ObjectId& new_array)
169      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
170
171  static bool MatchType(JDWP::RefTypeId instClassId, JDWP::RefTypeId classId)
172      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
173
174  /*
175   * Method and Field
176   */
177  static std::string GetMethodName(JDWP::RefTypeId refTypeId, JDWP::MethodId id)
178      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
179  static JDWP::JdwpError OutputDeclaredFields(JDWP::RefTypeId refTypeId, bool withGeneric,
180                                              JDWP::ExpandBuf* pReply)
181      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
182  static JDWP::JdwpError OutputDeclaredMethods(JDWP::RefTypeId refTypeId, bool withGeneric,
183                                               JDWP::ExpandBuf* pReply)
184      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
185  static JDWP::JdwpError OutputDeclaredInterfaces(JDWP::RefTypeId refTypeId,
186                                                  JDWP::ExpandBuf* pReply)
187      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
188  static void OutputLineTable(JDWP::RefTypeId refTypeId, JDWP::MethodId methodId,
189                              JDWP::ExpandBuf* pReply)
190      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
191  static void OutputVariableTable(JDWP::RefTypeId refTypeId, JDWP::MethodId id, bool withGeneric,
192                                  JDWP::ExpandBuf* pReply)
193      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
194
195  static JDWP::JdwpTag GetFieldBasicTag(JDWP::FieldId fieldId)
196      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
197  static JDWP::JdwpTag GetStaticFieldBasicTag(JDWP::FieldId fieldId)
198      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);;
199  static JDWP::JdwpError GetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId,
200                                       JDWP::ExpandBuf* pReply)
201      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
202  static JDWP::JdwpError SetFieldValue(JDWP::ObjectId objectId, JDWP::FieldId fieldId,
203                                       uint64_t value, int width)
204      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
205  static JDWP::JdwpError GetStaticFieldValue(JDWP::RefTypeId refTypeId, JDWP::FieldId fieldId,
206                                             JDWP::ExpandBuf* pReply)
207      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
208  static JDWP::JdwpError SetStaticFieldValue(JDWP::FieldId fieldId, uint64_t value, int width)
209      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
210
211  static std::string StringToUtf8(JDWP::ObjectId strId)
212      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
213
214  /*
215   * Thread, ThreadGroup, Frame
216   */
217  static bool GetThreadName(JDWP::ObjectId threadId, std::string& name)
218      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_)
219      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_);
220  static JDWP::JdwpError GetThreadGroup(JDWP::ObjectId threadId, JDWP::ExpandBuf* pReply);
221  static std::string GetThreadGroupName(JDWP::ObjectId threadGroupId);
222  static JDWP::ObjectId GetThreadGroupParent(JDWP::ObjectId threadGroupId)
223      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
224  static JDWP::ObjectId GetSystemThreadGroupId()
225      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
226  static JDWP::ObjectId GetMainThreadGroupId();
227
228  static bool GetThreadStatus(JDWP::ObjectId threadId, JDWP::JdwpThreadStatus* pThreadStatus, JDWP::JdwpSuspendStatus* pSuspendStatus);
229  static JDWP::JdwpError GetThreadDebugSuspendCount(JDWP::ObjectId threadId, JDWP::ExpandBuf* pReply);
230  static bool ThreadExists(JDWP::ObjectId threadId);
231  static bool IsSuspended(JDWP::ObjectId threadId);
232  //static void WaitForSuspend(JDWP::ObjectId threadId);
233
234  // Fills 'thread_ids' with the threads in the given thread group. If thread_group_id == 0,
235  // returns all threads.
236  static void GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& thread_ids)
237      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_)
238      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
239  static void GetChildThreadGroups(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& child_thread_group_ids);
240
241  static int GetThreadFrameCount(JDWP::ObjectId threadId);
242  static JDWP::JdwpError GetThreadFrames(JDWP::ObjectId thread_id, size_t start_frame,
243                                         size_t frame_count, JDWP::ExpandBuf* buf)
244      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
245
246  static JDWP::ObjectId GetThreadSelfId()
247      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
248  static void SuspendVM()
249      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_,
250                     GlobalSynchronization::thread_suspend_count_lock_);
251  static void ResumeVM();
252  static JDWP::JdwpError SuspendThread(JDWP::ObjectId threadId, bool request_suspension = true)
253      LOCKS_EXCLUDED(GlobalSynchronization::mutator_lock_,
254                     GlobalSynchronization::thread_list_lock_,
255                     GlobalSynchronization::thread_suspend_count_lock_);
256
257  static void ResumeThread(JDWP::ObjectId threadId)
258      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_,
259                     GlobalSynchronization::thread_suspend_count_lock_)
260      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
261  static void SuspendSelf();
262
263  static JDWP::JdwpError GetThisObject(JDWP::ObjectId thread_id, JDWP::FrameId frame_id,
264                                       JDWP::ObjectId* result)
265      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_,
266                     GlobalSynchronization::thread_suspend_count_lock_)
267      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
268  static void GetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot,
269                            JDWP::JdwpTag tag, uint8_t* buf, size_t expectedLen)
270      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
271  static void SetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot,
272                            JDWP::JdwpTag tag, uint64_t value, size_t width)
273      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
274
275  /*
276   * Debugger notification
277   */
278  enum {
279    kBreakpoint     = 0x01,
280    kSingleStep     = 0x02,
281    kMethodEntry    = 0x04,
282    kMethodExit     = 0x08,
283  };
284  static void PostLocationEvent(const Method* method, int pcOffset, Object* thisPtr, int eventFlags)
285      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
286  static void PostException(Thread* thread, JDWP::FrameId throw_frame_id, Method* throw_method,
287                            uint32_t throw_dex_pc, Method* catch_method, uint32_t catch_dex_pc,
288                            Throwable* exception)
289      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
290  static void PostThreadStart(Thread* t)
291      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
292  static void PostThreadDeath(Thread* t)
293      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
294  static void PostClassPrepare(Class* c)
295      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
296
297  static void UpdateDebugger(int32_t dex_pc, Thread* self)
298      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
299
300  static void WatchLocation(const JDWP::JdwpLocation* pLoc)
301      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
302  static void UnwatchLocation(const JDWP::JdwpLocation* pLoc)
303      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
304  static JDWP::JdwpError ConfigureStep(JDWP::ObjectId threadId, JDWP::JdwpStepSize size,
305                                       JDWP::JdwpStepDepth depth)
306      LOCKS_EXCLUDED(gBreakpointsLock)
307      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
308  static void UnconfigureStep(JDWP::ObjectId threadId);
309
310  static JDWP::JdwpError InvokeMethod(JDWP::ObjectId threadId, JDWP::ObjectId objectId,
311                                      JDWP::RefTypeId classId, JDWP::MethodId methodId,
312                                      uint32_t arg_count, uint64_t* arg_values,
313                                      JDWP::JdwpTag* arg_types, uint32_t options,
314                                      JDWP::JdwpTag* pResultTag, uint64_t* pResultValue,
315                                      JDWP::ObjectId* pExceptObj)
316      LOCKS_EXCLUDED(GlobalSynchronization::thread_list_lock_,
317                     GlobalSynchronization::thread_suspend_count_lock_)
318      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
319  static void ExecuteMethod(DebugInvokeReq* pReq);
320
321  /* perform "late registration" of an object ID */
322  static void RegisterObjectId(JDWP::ObjectId id);
323
324  /*
325   * DDM support.
326   */
327  static void DdmSendThreadNotification(Thread* t, uint32_t type)
328      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
329  static void DdmSetThreadNotification(bool enable);
330  static bool DdmHandlePacket(const uint8_t* buf, int dataLen, uint8_t** pReplyBuf, int* pReplyLen);
331  static void DdmConnected() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
332  static void DdmDisconnected() SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
333  static void DdmSendChunk(uint32_t type, const std::vector<uint8_t>& bytes)
334      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
335  static void DdmSendChunk(uint32_t type, size_t len, const uint8_t* buf)
336      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
337  static void DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count)
338      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
339
340  /*
341   * Recent allocation tracking support.
342   */
343  static void RecordAllocation(Class* type, size_t byte_count)
344      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
345  static void SetAllocTrackingEnabled(bool enabled);
346  static inline bool IsAllocTrackingEnabled() { return recent_allocation_records_ != NULL; }
347  static jbyteArray GetRecentAllocations()
348      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
349  static void DumpRecentAllocations();
350
351  enum HpifWhen {
352    HPIF_WHEN_NEVER = 0,
353    HPIF_WHEN_NOW = 1,
354    HPIF_WHEN_NEXT_GC = 2,
355    HPIF_WHEN_EVERY_GC = 3
356  };
357  static int DdmHandleHpifChunk(HpifWhen when)
358      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
359
360  enum HpsgWhen {
361    HPSG_WHEN_NEVER = 0,
362    HPSG_WHEN_EVERY_GC = 1,
363  };
364  enum HpsgWhat {
365    HPSG_WHAT_MERGED_OBJECTS = 0,
366    HPSG_WHAT_DISTINCT_OBJECTS = 1,
367  };
368  static bool DdmHandleHpsgNhsgChunk(HpsgWhen when, HpsgWhat what, bool native);
369
370  static void DdmSendHeapInfo(HpifWhen reason)
371      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
372  static void DdmSendHeapSegments(bool native)
373      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
374
375 private:
376  static void DdmBroadcast(bool) SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
377  static void PostThreadStartOrStop(Thread*, uint32_t)
378      SHARED_LOCKS_REQUIRED(GlobalSynchronization::mutator_lock_);
379
380  static AllocRecord* recent_allocation_records_;
381};
382
383#define CHUNK_TYPE(_name) \
384    static_cast<uint32_t>((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
385
386}  // namespace art
387
388#endif  // ART_DEBUGGER_H_
389