Chromium Code Reviews| Index: runtime/bin/dbg_message.h |
| =================================================================== |
| --- runtime/bin/dbg_message.h (revision 0) |
| +++ runtime/bin/dbg_message.h (revision 0) |
| @@ -0,0 +1,195 @@ |
| +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +#ifndef BIN_DBG_MESSAGE_H_ |
| +#define BIN_DBG_MESSAGE_H_ |
| + |
| +#include "bin/builtin.h" |
| +#include "bin/utils.h" |
| + |
| +#include "include/dart_debugger_api.h" |
| + |
| +#include "platform/globals.h" |
| +#include "platform/json.h" |
| +#include "platform/thread.h" |
| + |
| + |
| +// TODO(hausner): Need better error handling. |
| +#define ASSERT_NOT_ERROR(handle) \ |
| + ASSERT(!Dart_IsError(handle)) |
| + |
| +#define RETURN_IF_ERROR(handle) \ |
| + if (Dart_IsError(handle)) { \ |
| + return Dart_GetError(handle); \ |
| + } |
| + |
| + |
| +// Class to parse a JSON debug command message. |
| +class MessageParser { |
| + public: |
| + MessageParser(const char* buf, int buf_length) |
| + : buf_(buf), buf_length_(buf_length) { |
| + } |
| + ~MessageParser() { } |
| + |
| + // Accessors. |
| + const char* buf() const { return buf_; } |
| + |
| + bool IsValidMessage() const; |
| + int MessageId() const; |
| + |
| + const char* Params() const; |
| + intptr_t GetIntParam(const char* name) const; |
| + intptr_t GetOptIntParam(const char* name, intptr_t default_val) const; |
| + |
| + // GetStringParam mallocs the buffer that it returns. Caller must free. |
| + char* GetStringParam(const char* name) const; |
| + |
| + private: |
| + const char* buf_; |
| + int buf_length_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(MessageParser); |
| +}; |
| + |
| + |
| +// Class which represents a debug command message and handles it. |
| +class DbgMessage { |
| + public: |
| + DbgMessage(DbgMessage* next, int32_t cmd_idx, const char* start, |
| + const char* end, int debug_fd) |
| + : next_(next), cmd_idx_(cmd_idx), |
| + buffer_(NULL), buffer_len_(end - start), |
| + debug_fd_(debug_fd), request_resume_(false) { |
| + buffer_ = reinterpret_cast<char*>(malloc(buffer_len_)); |
| + ASSERT(buffer_ != NULL); |
| + memmove(buffer_, start, buffer_len_); |
| + } |
| + ~DbgMessage() { |
| + next_ = NULL; |
| + free(buffer_); |
| + } |
| + |
| + // Accessors. |
| + DbgMessage* next() const { return next_; } |
| + char* buffer() const { return buffer_; } |
| + int32_t buffer_len() const { return buffer_len_; } |
| + int debug_fd() const { return debug_fd_; } |
| + 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.
|
| + void set_request_resume(bool value) { request_resume_ = value; } |
| + |
| + // Handle debugger command message. |
| + void HandleMessage(); |
| + |
| + // Send reply after successful handling of command. |
| + void SendReply(dart::TextBuffer* msg); |
| + |
| + // Reply error returned by the command handler. |
| + void SendErrorReply(int msg_id, const char* err_msg); |
| + |
| + // Handlers for specific commands, they are static because these |
| + // functions are populated as function pointers into a dispatch table. |
| + static void HandleResumeCmd(DbgMessage* msg); |
| + static void HandleStepIntoCmd(DbgMessage* msg); |
| + static void HandleStepOverCmd(DbgMessage* msg); |
| + static void HandleStepOutCmd(DbgMessage* msg); |
| + static void HandleGetLibrariesCmd(DbgMessage* msg); |
| + static void HandleGetClassPropsCmd(DbgMessage* msg); |
| + static void HandleGetLibPropsCmd(DbgMessage* msg); |
| + static void HandleSetLibPropsCmd(DbgMessage* msg); |
| + static void HandleGetGlobalsCmd(DbgMessage* msg); |
| + static void HandleGetObjPropsCmd(DbgMessage* msg); |
| + static void HandleGetListCmd(DbgMessage* msg); |
| + static void HandleGetScriptURLsCmd(DbgMessage* msg); |
| + static void HandleGetSourceCmd(DbgMessage* msg); |
| + static void HandleGetStackTraceCmd(DbgMessage* msg); |
| + static void HandlePauseOnExcCmd(DbgMessage* msg); |
| + static void HandleSetBpCmd(DbgMessage* msg); |
| + static void HandleRemBpCmd(DbgMessage* msg); |
| + |
| + private: |
| + DbgMessage* next_; // Next message in the queue. |
| + int32_t cmd_idx_; // Isolate specific debugger command index. |
| + char* buffer_; // Debugger command message. |
| + int32_t buffer_len_; // Length of the debugger command message. |
| + int debug_fd_; // Debugger connection on which replies are to be sent. |
| + bool request_resume_; // True if command requests execution to resume. |
| + |
| + DISALLOW_IMPLICIT_CONSTRUCTORS(DbgMessage); |
| +}; |
| + |
| + |
| +// Class which represents a queue of debug command messages sent to an isolate. |
| +class DbgMessageQueue { |
| + public: |
| + static const int32_t kInvalidCommand = -1; |
| + |
| + DbgMessageQueue() : is_running_(true), |
| + is_interrupted_(false), |
| + msglist_(NULL), |
| + queued_output_messages_(64) { |
| + } |
| + ~DbgMessageQueue() { |
| + // Cleanup the message queue |
| + } |
| + |
| + // Add specified debug command message to the queue. |
| + void AddMessage(int32_t cmd_idx, |
| + const char* start, |
| + const char* end, |
| + int debug_fd); |
| + |
| + // Handle all debug command messages in the queue. |
| + void HandleMessages(); |
| + |
| + // Queue output messages, these are sent out when we hit an event. |
| + void QueueOutputMsg(dart::TextBuffer* msg); |
| + |
| + // Send all queued messages over to the debugger. |
| + void SendQueuedMsgs(); |
| + |
| + // Send breakpoint event message over to the debugger. |
| + void SendBreakpointEvent(Dart_StackTrace trace); |
| + |
| + // Send Exception event message over to the debugger. |
| + void SendExceptionEvent(Dart_Handle exception, Dart_StackTrace trace); |
| + |
| + // Initialize the message queue processing by setting up the appropriate |
| + // handlers. |
| + static void Initialize(); |
| + |
| + // Parses the input message and returns the command index if the message |
| + // contains a valid isolate specific command. |
| + // It returns kInvalidCommand otherwise. |
| + static int32_t LookupIsolateCommand(const char* buf, int32_t buflen); |
| + |
| + // Get Debugger Message Queue corresponding to the Isolate. |
| + static DbgMessageQueue* GetIsolateMessageQueue(Dart_Isolate isolate); |
| + |
| + // Generic handlers for breakpoints, exceptions and delayed breakpoint |
| + // resolution. |
| + static void BptResolvedHandler(intptr_t bp_id, |
| + Dart_Handle url, |
| + intptr_t line_number); |
| + static void BreakpointHandler(Dart_Breakpoint bpt, Dart_StackTrace trace); |
| + static void ExceptionThrownHandler(Dart_Handle exception, |
| + Dart_StackTrace stack_trace); |
| + |
| + private: |
| + bool is_running_; // True if isolate is running and not in the debugger loop. |
| + bool is_interrupted_; // True if interrupt command is pending. |
| + |
| + DbgMessage* msglist_; // List of debugger messages received. |
| + |
| + // Text buffer that accumulates messages to be output. |
| + dart::TextBuffer queued_output_messages_; |
| + |
| + // The waits on this condition variable when it needs to process |
| + // debug messages. |
| + dart::Monitor msg_queue_lock_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(DbgMessageQueue); |
| +}; |
| + |
| +#endif // BIN_DBG_MESSAGE_H_ |