Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 #ifndef BIN_DBG_MESSAGE_H_ | |
| 6 #define BIN_DBG_MESSAGE_H_ | |
| 7 | |
| 8 #include "bin/builtin.h" | |
| 9 #include "bin/utils.h" | |
| 10 | |
| 11 #include "include/dart_debugger_api.h" | |
| 12 | |
| 13 #include "platform/globals.h" | |
| 14 #include "platform/json.h" | |
| 15 #include "platform/thread.h" | |
| 16 | |
| 17 | |
| 18 // TODO(hausner): Need better error handling. | |
| 19 #define ASSERT_NOT_ERROR(handle) \ | |
| 20 ASSERT(!Dart_IsError(handle)) | |
| 21 | |
| 22 #define RETURN_IF_ERROR(handle) \ | |
| 23 if (Dart_IsError(handle)) { \ | |
| 24 return Dart_GetError(handle); \ | |
| 25 } | |
| 26 | |
| 27 | |
| 28 // Class to parse a JSON debug command message. | |
| 29 class MessageParser { | |
| 30 public: | |
| 31 MessageParser(const char* buf, int buf_length) | |
| 32 : buf_(buf), buf_length_(buf_length) { | |
| 33 } | |
| 34 ~MessageParser() { } | |
| 35 | |
| 36 // Accessors. | |
| 37 const char* buf() const { return buf_; } | |
| 38 | |
| 39 bool IsValidMessage() const; | |
| 40 int MessageId() const; | |
| 41 | |
| 42 const char* Params() const; | |
| 43 intptr_t GetIntParam(const char* name) const; | |
| 44 intptr_t GetOptIntParam(const char* name, intptr_t default_val) const; | |
| 45 | |
| 46 // GetStringParam mallocs the buffer that it returns. Caller must free. | |
| 47 char* GetStringParam(const char* name) const; | |
| 48 | |
| 49 private: | |
| 50 const char* buf_; | |
| 51 int buf_length_; | |
| 52 | |
| 53 DISALLOW_COPY_AND_ASSIGN(MessageParser); | |
| 54 }; | |
| 55 | |
| 56 | |
| 57 // Class which represents a debug command message and handles it. | |
| 58 class DbgMessage { | |
| 59 public: | |
| 60 DbgMessage(DbgMessage* next, int32_t cmd_idx, const char* start, | |
| 61 const char* end, int debug_fd) | |
| 62 : next_(next), cmd_idx_(cmd_idx), | |
| 63 buffer_(NULL), buffer_len_(end - start), | |
| 64 debug_fd_(debug_fd), request_resume_(false) { | |
| 65 buffer_ = reinterpret_cast<char*>(malloc(buffer_len_)); | |
| 66 ASSERT(buffer_ != NULL); | |
| 67 memmove(buffer_, start, buffer_len_); | |
| 68 } | |
| 69 ~DbgMessage() { | |
| 70 next_ = NULL; | |
| 71 free(buffer_); | |
| 72 } | |
| 73 | |
| 74 // Accessors. | |
| 75 DbgMessage* next() const { return next_; } | |
| 76 char* buffer() const { return buffer_; } | |
| 77 int32_t buffer_len() const { return buffer_len_; } | |
| 78 int debug_fd() const { return debug_fd_; } | |
| 79 bool request_resume() const { return request_resume_; } | |
|
hausner
2012/09/28 17:03:01
It's a matter of taste, but I would eliminate the
siva
2012/09/28 23:32:29
Done.
| |
| 80 void set_request_resume(bool value) { request_resume_ = value; } | |
| 81 | |
| 82 // Handle debugger command message. | |
| 83 void HandleMessage(); | |
| 84 | |
| 85 // Send reply after successful handling of command. | |
| 86 void SendReply(dart::TextBuffer* msg); | |
| 87 | |
| 88 // Reply error returned by the command handler. | |
| 89 void SendErrorReply(int msg_id, const char* err_msg); | |
| 90 | |
| 91 // Handlers for specific commands, they are static because these | |
| 92 // functions are populated as function pointers into a dispatch table. | |
| 93 static void HandleResumeCmd(DbgMessage* msg); | |
| 94 static void HandleStepIntoCmd(DbgMessage* msg); | |
| 95 static void HandleStepOverCmd(DbgMessage* msg); | |
| 96 static void HandleStepOutCmd(DbgMessage* msg); | |
| 97 static void HandleGetLibrariesCmd(DbgMessage* msg); | |
| 98 static void HandleGetClassPropsCmd(DbgMessage* msg); | |
| 99 static void HandleGetLibPropsCmd(DbgMessage* msg); | |
| 100 static void HandleSetLibPropsCmd(DbgMessage* msg); | |
| 101 static void HandleGetGlobalsCmd(DbgMessage* msg); | |
| 102 static void HandleGetObjPropsCmd(DbgMessage* msg); | |
| 103 static void HandleGetListCmd(DbgMessage* msg); | |
| 104 static void HandleGetScriptURLsCmd(DbgMessage* msg); | |
| 105 static void HandleGetSourceCmd(DbgMessage* msg); | |
| 106 static void HandleGetStackTraceCmd(DbgMessage* msg); | |
| 107 static void HandlePauseOnExcCmd(DbgMessage* msg); | |
| 108 static void HandleSetBpCmd(DbgMessage* msg); | |
| 109 static void HandleRemBpCmd(DbgMessage* msg); | |
| 110 | |
| 111 private: | |
| 112 DbgMessage* next_; // Next message in the queue. | |
| 113 int32_t cmd_idx_; // Isolate specific debugger command index. | |
| 114 char* buffer_; // Debugger command message. | |
| 115 int32_t buffer_len_; // Length of the debugger command message. | |
| 116 int debug_fd_; // Debugger connection on which replies are to be sent. | |
| 117 bool request_resume_; // True if command requests execution to resume. | |
| 118 | |
| 119 DISALLOW_IMPLICIT_CONSTRUCTORS(DbgMessage); | |
| 120 }; | |
| 121 | |
| 122 | |
| 123 // Class which represents a queue of debug command messages sent to an isolate. | |
| 124 class DbgMessageQueue { | |
| 125 public: | |
| 126 static const int32_t kInvalidCommand = -1; | |
| 127 | |
| 128 DbgMessageQueue() : is_running_(true), | |
| 129 is_interrupted_(false), | |
| 130 msglist_(NULL), | |
| 131 queued_output_messages_(64) { | |
| 132 } | |
| 133 ~DbgMessageQueue() { | |
| 134 // Cleanup the message queue | |
| 135 } | |
| 136 | |
| 137 // Add specified debug command message to the queue. | |
| 138 void AddMessage(int32_t cmd_idx, | |
| 139 const char* start, | |
| 140 const char* end, | |
| 141 int debug_fd); | |
| 142 | |
| 143 // Handle all debug command messages in the queue. | |
| 144 void HandleMessages(); | |
| 145 | |
| 146 // Queue output messages, these are sent out when we hit an event. | |
| 147 void QueueOutputMsg(dart::TextBuffer* msg); | |
| 148 | |
| 149 // Send all queued messages over to the debugger. | |
| 150 void SendQueuedMsgs(); | |
| 151 | |
| 152 // Send breakpoint event message over to the debugger. | |
| 153 void SendBreakpointEvent(Dart_StackTrace trace); | |
| 154 | |
| 155 // Send Exception event message over to the debugger. | |
| 156 void SendExceptionEvent(Dart_Handle exception, Dart_StackTrace trace); | |
| 157 | |
| 158 // Initialize the message queue processing by setting up the appropriate | |
| 159 // handlers. | |
| 160 static void Initialize(); | |
| 161 | |
| 162 // Parses the input message and returns the command index if the message | |
| 163 // contains a valid isolate specific command. | |
| 164 // It returns kInvalidCommand otherwise. | |
| 165 static int32_t LookupIsolateCommand(const char* buf, int32_t buflen); | |
| 166 | |
| 167 // Get Debugger Message Queue corresponding to the Isolate. | |
| 168 static DbgMessageQueue* GetIsolateMessageQueue(Dart_Isolate isolate); | |
| 169 | |
| 170 // Generic handlers for breakpoints, exceptions and delayed breakpoint | |
| 171 // resolution. | |
| 172 static void BptResolvedHandler(intptr_t bp_id, | |
| 173 Dart_Handle url, | |
| 174 intptr_t line_number); | |
| 175 static void BreakpointHandler(Dart_Breakpoint bpt, Dart_StackTrace trace); | |
| 176 static void ExceptionThrownHandler(Dart_Handle exception, | |
| 177 Dart_StackTrace stack_trace); | |
| 178 | |
| 179 private: | |
| 180 bool is_running_; // True if isolate is running and not in the debugger loop. | |
| 181 bool is_interrupted_; // True if interrupt command is pending. | |
| 182 | |
| 183 DbgMessage* msglist_; // List of debugger messages received. | |
| 184 | |
| 185 // Text buffer that accumulates messages to be output. | |
| 186 dart::TextBuffer queued_output_messages_; | |
| 187 | |
| 188 // The waits on this condition variable when it needs to process | |
| 189 // debug messages. | |
| 190 dart::Monitor msg_queue_lock_; | |
| 191 | |
| 192 DISALLOW_COPY_AND_ASSIGN(DbgMessageQueue); | |
| 193 }; | |
| 194 | |
| 195 #endif // BIN_DBG_MESSAGE_H_ | |
| OLD | NEW |