Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(732)

Side by Side Diff: runtime/bin/dbg_connection.cc

Issue 10392017: Support more debugger commands in the wire protocol (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/dbg_connection.h ('k') | runtime/platform/c99_support_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "bin/dbg_connection.h" 5 #include "bin/dbg_connection.h"
6 #include "bin/dartutils.h" 6 #include "bin/dartutils.h"
7 #include "bin/socket.h" 7 #include "bin/socket.h"
8 #include "bin/thread.h" 8 #include "bin/thread.h"
9 #include "bin/utils.h" 9 #include "bin/utils.h"
10 10
11 #include "platform/globals.h" 11 #include "platform/globals.h"
12 #include "platform/json.h" 12 #include "platform/json.h"
13 #include "platform/thread.h" 13 #include "platform/thread.h"
14 #include "platform/utils.h" 14 #include "platform/utils.h"
15 15
16 #include "include/dart_api.h" 16 #include "include/dart_api.h"
17 17
18 18
19 int DebuggerConnectionHandler::listener_fd_ = -1; 19 int DebuggerConnectionHandler::listener_fd_ = -1;
20 int DebuggerConnectionHandler::debugger_fd_ = -1; 20 int DebuggerConnectionHandler::debugger_fd_ = -1;
21 dart::Monitor DebuggerConnectionHandler::is_connected_; 21 dart::Monitor DebuggerConnectionHandler::is_connected_;
22 MessageBuffer* DebuggerConnectionHandler::msgbuf_ = NULL; 22 MessageBuffer* DebuggerConnectionHandler::msgbuf_ = NULL;
23 23
24 bool DebuggerConnectionHandler::handler_started_ = false; 24 bool DebuggerConnectionHandler::handler_started_ = false;
25 bool DebuggerConnectionHandler::request_resume_ = false;
25 26
26 27
27 // TODO(hausner): Need better error handling. 28 // TODO(hausner): Need better error handling.
28 #define ASSERT_NOT_ERROR(handle) \ 29 #define ASSERT_NOT_ERROR(handle) \
29 ASSERT(!Dart_IsError(handle)) 30 ASSERT(!Dart_IsError(handle))
30 31
32 typedef void (*CommandHandler)(const char* json_cmd);
33
34 struct JSONDebuggerCommand {
35 const char* cmd_string;
36 CommandHandler handler_function;
37 };
38
31 39
32 class MessageBuffer { 40 class MessageBuffer {
33 public: 41 public:
34 explicit MessageBuffer(int fd); 42 explicit MessageBuffer(int fd);
35 ~MessageBuffer(); 43 ~MessageBuffer();
36 void ReadData(); 44 void ReadData();
37 bool IsValidMessage() const; 45 bool IsValidMessage() const;
38 void PopMessage(); 46 void PopMessage();
39 int MessageId() const; 47 int MessageId() const;
48 const char* Params() const;
40 char* buf() const { return buf_; } 49 char* buf() const { return buf_; }
41 bool Alive() const { return connection_is_alive_; } 50 bool Alive() const { return connection_is_alive_; }
42 51
43 private: 52 private:
44 static const int kInitialBufferSize = 256; 53 static const int kInitialBufferSize = 256;
45 char* buf_; 54 char* buf_;
46 int buf_length_; 55 int buf_length_;
47 int fd_; 56 int fd_;
48 int data_length_; 57 int data_length_;
49 bool connection_is_alive_; 58 bool connection_is_alive_;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 dart::JSONReader r(buf_); 97 dart::JSONReader r(buf_);
89 r.Seek("id"); 98 r.Seek("id");
90 if (r.Type() == dart::JSONReader::kInteger) { 99 if (r.Type() == dart::JSONReader::kInteger) {
91 return atoi(r.ValueChars()); 100 return atoi(r.ValueChars());
92 } else { 101 } else {
93 return -1; 102 return -1;
94 } 103 }
95 } 104 }
96 105
97 106
107 const char* MessageBuffer::Params() const {
108 dart::JSONReader r(buf_);
109 r.Seek("param");
110 if (r.Type() == dart::JSONReader::kObject) {
111 return r.ValueChars();
112 } else {
113 return NULL;
114 }
115 }
116
117
98 void MessageBuffer::ReadData() { 118 void MessageBuffer::ReadData() {
99 ASSERT(data_length_ >= 0); 119 ASSERT(data_length_ >= 0);
100 ASSERT(data_length_ < buf_length_); 120 ASSERT(data_length_ < buf_length_);
101 int max_read = buf_length_ - data_length_ - 1; 121 int max_read = buf_length_ - data_length_ - 1;
102 if (max_read == 0) { 122 if (max_read == 0) {
103 // TODO(hausner): 123 // TODO(hausner):
104 // Buffer is full. What should we do if there is no valid message 124 // Buffer is full. What should we do if there is no valid message
105 // in the buffer? This might be possible if the client sends a message 125 // in the buffer? This might be possible if the client sends a message
106 // that's larger than the buffer, of if the client sends malformed 126 // that's larger than the buffer, of if the client sends malformed
107 // messages that keep piling up. 127 // messages that keep piling up.
(...skipping 30 matching lines...) Expand all
138 } 158 }
139 } 159 }
140 160
141 161
142 static bool IsValidJSON(const char* msg) { 162 static bool IsValidJSON(const char* msg) {
143 dart::JSONReader r(msg); 163 dart::JSONReader r(msg);
144 return r.EndOfObject() != NULL; 164 return r.EndOfObject() != NULL;
145 } 165 }
146 166
147 167
148 void DebuggerConnectionHandler::HandleResumeCmd() { 168 void DebuggerConnectionHandler::SendError(int msg_id,
169 const char* format, ...) {
170 dart::TextBuffer msg(64);
171 msg.Printf("{\"id\": %d, \"error\": \"", msg_id);
172 va_list args;
173 va_start(args, format);
174 msg.Printf(format, args);
175 va_end(args);
176 msg.Printf("\"}");
177 Socket::Write(debugger_fd_, msg.buf(), msg.length());
178 // TODO(hausner): Error checking. Probably just shut down the debugger
179 // session if we there is an error while writing.
180 }
181
182
183 void DebuggerConnectionHandler::HandleResumeCmd(const char* json_msg) {
149 int msg_id = msgbuf_->MessageId(); 184 int msg_id = msgbuf_->MessageId();
150 dart::TextBuffer msg(64); 185 dart::TextBuffer msg(64);
151 msg.Printf("{ \"id\": %d }", msg_id); 186 msg.Printf("{ \"id\": %d }", msg_id);
152 Socket::Write(debugger_fd_, msg.buf(), msg.length()); 187 Socket::Write(debugger_fd_, msg.buf(), msg.length());
153 // TODO(hausner): Error checking. Probably just shut down the debugger 188 // TODO(hausner): Error checking. Probably just shut down the debugger
154 // session if we there is an error while writing. 189 // session if we there is an error while writing.
190 request_resume_ = true;
191 }
192
193
194 void DebuggerConnectionHandler::HandleStepIntoCmd(const char* json_msg) {
195 Dart_Handle res = Dart_SetStepInto();
196 ASSERT_NOT_ERROR(res);
197 HandleResumeCmd(json_msg);
198 }
199
200
201 void DebuggerConnectionHandler::HandleStepOutCmd(const char* json_msg) {
202 Dart_Handle res = Dart_SetStepOut();
203 ASSERT_NOT_ERROR(res);
204 HandleResumeCmd(json_msg);
205 }
206
207
208 void DebuggerConnectionHandler::HandleStepOverCmd(const char* json_msg) {
209 Dart_Handle res = Dart_SetStepOver();
210 ASSERT_NOT_ERROR(res);
211 HandleResumeCmd(json_msg);
212 }
213
214
215 void DebuggerConnectionHandler::HandleGetScriptURLsCmd(const char* json_msg) {
216 int msg_id = msgbuf_->MessageId();
217 dart::TextBuffer msg(64);
218 const char* params = msgbuf_->Params();
219 ASSERT(params != NULL);
220 dart::JSONReader pr(params);
221 pr.Seek("library");
222 ASSERT(pr.Type() == dart::JSONReader::kString);
223 char lib_url_chars[128];
224 pr.GetValueChars(lib_url_chars, sizeof(lib_url_chars));
225 Dart_Handle lib_url = Dart_NewString(lib_url_chars);
226 ASSERT_NOT_ERROR(lib_url);
227 Dart_Handle urls = Dart_GetScriptURLs(lib_url);
228 if (Dart_IsError(urls)) {
229 SendError(msg_id, "Error: '%s'.", Dart_GetError(urls));
230 return;
231 }
232 ASSERT(Dart_IsList(urls));
233 intptr_t num_urls = 0;
234 Dart_ListLength(urls, &num_urls);
235 msg.Printf("{ \"id\": %d, ", msg_id);
236 msg.Printf("\"result\": { \"urls\": [");
237 for (int i = 0; i < num_urls; i++) {
238 Dart_Handle script_url = Dart_ListGetAt(urls, i);
239 ASSERT(Dart_IsString(script_url));
240 char const* chars;
241 Dart_StringToCString(lib_url, &chars);
242 msg.Printf("%s\"%s\"", (i == 0) ? "" : ", ", chars);
243 }
244 msg.Printf("] }}");
245 Socket::Write(debugger_fd_, msg.buf(), msg.length());
246 // TODO(hausner): Error checking. Probably just shut down the debugger
247 // session if we there is an error while writing.
248 }
249
250
251 void DebuggerConnectionHandler::HandleGetLibraryURLsCmd(const char* json_msg) {
252 int msg_id = msgbuf_->MessageId();
253 dart::TextBuffer msg(64);
254 msg.Printf("{ \"id\": %d, \"result\": { \"urls\": [", msg_id);
255 Dart_Handle urls = Dart_GetLibraryURLs();
256 ASSERT_NOT_ERROR(urls);
257 intptr_t num_libs;
258 Dart_ListLength(urls, &num_libs);
259 for (int i = 0; i < num_libs; i++) {
260 Dart_Handle lib_url = Dart_ListGetAt(urls, i);
261 ASSERT(Dart_IsString(lib_url));
262 char const* chars;
263 Dart_StringToCString(lib_url, &chars);
264 msg.Printf("%s\"%s\"", (i == 0) ? "" : ", ", chars);
265 }
266 msg.Printf("] }}");
267 Socket::Write(debugger_fd_, msg.buf(), msg.length());
268 // TODO(hausner): Error checking. Probably just shut down the debugger
269 // session if we there is an error while writing.
155 } 270 }
156 271
157 272
158 void DebuggerConnectionHandler::HandleMessages() { 273 void DebuggerConnectionHandler::HandleMessages() {
274 static JSONDebuggerCommand debugger_commands[] = {
275 { "resume", HandleResumeCmd },
276 { "getLibraryURLs", HandleGetLibraryURLsCmd},
277 { "getScriptURLs", HandleGetScriptURLsCmd },
278 { "stepInto", HandleStepIntoCmd },
279 { "stepOut", HandleStepOutCmd },
280 { "stepOver", HandleStepOverCmd },
281 { NULL, NULL }
282 };
283
159 for (;;) { 284 for (;;) {
160 while (!msgbuf_->IsValidMessage() && msgbuf_->Alive()) { 285 while (!msgbuf_->IsValidMessage() && msgbuf_->Alive()) {
161 msgbuf_->ReadData(); 286 msgbuf_->ReadData();
162 } 287 }
163 if (!msgbuf_->Alive()) { 288 if (!msgbuf_->Alive()) {
164 return; 289 return;
165 } 290 }
166 dart::JSONReader r(msgbuf_->buf()); 291 dart::JSONReader r(msgbuf_->buf());
167 bool found = r.Seek("command"); 292 bool found = r.Seek("command");
168 if (r.Error()) { 293 if (r.Error()) {
169 FATAL("Illegal JSON message received"); 294 FATAL("Illegal JSON message received");
170 } 295 }
171 if (!found) { 296 if (!found) {
172 printf("'command' not found in JSON message: '%s'\n", msgbuf_->buf()); 297 printf("'command' not found in JSON message: '%s'\n", msgbuf_->buf());
173 msgbuf_->PopMessage(); 298 msgbuf_->PopMessage();
174 } else if (r.IsStringLiteral("resume")) { 299 }
175 HandleResumeCmd(); 300 int i = 0;
176 msgbuf_->PopMessage(); 301 bool is_handled = false;
177 return; 302 request_resume_ = false;
178 } else { 303 while (debugger_commands[i].cmd_string != NULL) {
304 if (r.IsStringLiteral(debugger_commands[i].cmd_string)) {
305 is_handled = true;
306 (*debugger_commands[i].handler_function)(msgbuf_->buf());
307 msgbuf_->PopMessage();
308 if (request_resume_) {
309 return;
310 }
311 break;
312 }
313 i++;
314 }
315 if (!is_handled) {
179 printf("unrecognized command received: '%s'\n", msgbuf_->buf()); 316 printf("unrecognized command received: '%s'\n", msgbuf_->buf());
180 msgbuf_->PopMessage(); 317 msgbuf_->PopMessage();
181 } 318 }
182 } 319 }
183 } 320 }
184 321
185 322
186 void DebuggerConnectionHandler::SendBreakpointEvent(Dart_Breakpoint bpt, 323 void DebuggerConnectionHandler::SendBreakpointEvent(Dart_Breakpoint bpt,
187 Dart_StackTrace trace) { 324 Dart_StackTrace trace) {
188 dart::TextBuffer msg(128); 325 dart::TextBuffer msg(128);
189 intptr_t trace_len = 0; 326 intptr_t trace_len = 0;
190 Dart_Handle res = Dart_StackTraceLength(trace, &trace_len); 327 Dart_Handle res = Dart_StackTraceLength(trace, &trace_len);
191 ASSERT_NOT_ERROR(res); 328 ASSERT_NOT_ERROR(res);
192 msg.Printf("{ \"command\" : \"paused\", \"params\" : "); 329 msg.Printf("{ \"event\": \"paused\", \"params\": ");
193 msg.Printf("{ \"callFrames\" : [ "); 330 msg.Printf("{ \"callFrames\" : [ ");
194 for (int i = 0; i < trace_len; i++) { 331 for (int i = 0; i < trace_len; i++) {
195 Dart_ActivationFrame frame; 332 Dart_ActivationFrame frame;
196 res = Dart_GetActivationFrame(trace, i, &frame); 333 res = Dart_GetActivationFrame(trace, i, &frame);
197 ASSERT_NOT_ERROR(res); 334 ASSERT_NOT_ERROR(res);
198 Dart_Handle func_name; 335 Dart_Handle func_name;
199 Dart_Handle script_url; 336 Dart_Handle script_url;
200 intptr_t line_number = 0; 337 intptr_t line_number = 0;
201 res = Dart_ActivationFrameInfo( 338 res = Dart_ActivationFrameInfo(
202 frame, &func_name, &script_url, &line_number); 339 frame, &func_name, &script_url, &line_number);
203 ASSERT_NOT_ERROR(res); 340 ASSERT_NOT_ERROR(res);
204 ASSERT(Dart_IsString(func_name)); 341 ASSERT(Dart_IsString(func_name));
205 const char* func_name_chars; 342 const char* func_name_chars;
206 Dart_StringToCString(func_name, &func_name_chars); 343 Dart_StringToCString(func_name, &func_name_chars);
207 msg.Printf("%s { \"functionName\" : \"%s\" , ", 344 msg.Printf("%s { \"functionName\": \"%s\" , ",
208 i > 0 ? "," : "", 345 i > 0 ? "," : "",
209 func_name_chars); 346 func_name_chars);
210 ASSERT(Dart_IsString(script_url)); 347 ASSERT(Dart_IsString(script_url));
211 const char* script_url_chars; 348 const char* script_url_chars;
212 Dart_StringToCString(script_url, &script_url_chars); 349 Dart_StringToCString(script_url, &script_url_chars);
213 msg.Printf("\"location\": { \"url\": \"%s\", \"lineNumber\": %d }}", 350 msg.Printf("\"location\": { \"url\": \"%s\", \"lineNumber\": %d }}",
214 script_url_chars, line_number); 351 script_url_chars, line_number);
215 } 352 }
216 msg.Printf("]}}"); 353 msg.Printf("]}}");
217 Socket::Write(debugger_fd_, msg.buf(), msg.length()); 354 Socket::Write(debugger_fd_, msg.buf(), msg.length());
218 ASSERT(IsValidJSON(msg.buf())); 355 ASSERT(IsValidJSON(msg.buf()));
219 } 356 }
220 357
221 358
222 void DebuggerConnectionHandler::BreakpointHandler(Dart_Breakpoint bpt, 359 void DebuggerConnectionHandler::BreakpointHandler(Dart_Breakpoint bpt,
223 Dart_StackTrace trace) { 360 Dart_StackTrace trace) {
224 { 361 {
225 MonitorLocker ml(&is_connected_); 362 MonitorLocker ml(&is_connected_);
226 while (!IsConnected()) { 363 while (!IsConnected()) {
227 printf("Waiting for debugger connection...\n"); 364 printf("Waiting for debugger connection...\n");
228 dart::Monitor::WaitResult res = ml.Wait(dart::Monitor::kNoTimeout); 365 dart::Monitor::WaitResult res = ml.Wait(dart::Monitor::kNoTimeout);
229 ASSERT(res == dart::Monitor::kNotified); 366 ASSERT(res == dart::Monitor::kNotified);
230 } 367 }
231 } 368 }
369 Dart_EnterScope();
232 SendBreakpointEvent(bpt, trace); 370 SendBreakpointEvent(bpt, trace);
233 HandleMessages(); 371 HandleMessages();
234 if (!msgbuf_->Alive()) { 372 if (!msgbuf_->Alive()) {
235 CloseDbgConnection(); 373 CloseDbgConnection();
236 } 374 }
375 Dart_ExitScope();
237 } 376 }
238 377
239 378
240 void DebuggerConnectionHandler::AcceptDbgConnection(int debugger_fd) { 379 void DebuggerConnectionHandler::AcceptDbgConnection(int debugger_fd) {
241 debugger_fd_ = debugger_fd; 380 debugger_fd_ = debugger_fd;
242 ASSERT(msgbuf_ == NULL); 381 ASSERT(msgbuf_ == NULL);
243 msgbuf_ = new MessageBuffer(debugger_fd_); 382 msgbuf_ = new MessageBuffer(debugger_fd_);
244 { 383 {
245 MonitorLocker ml(&is_connected_); 384 MonitorLocker ml(&is_connected_);
246 ml.Notify(); 385 ml.Notify();
(...skipping 22 matching lines...) Expand all
269 408
270 handler_started_ = true; 409 handler_started_ = true;
271 DebuggerConnectionImpl::StartHandler(port_number); 410 DebuggerConnectionImpl::StartHandler(port_number);
272 Dart_SetBreakpointHandler(BreakpointHandler); 411 Dart_SetBreakpointHandler(BreakpointHandler);
273 } 412 }
274 413
275 414
276 DebuggerConnectionHandler::~DebuggerConnectionHandler() { 415 DebuggerConnectionHandler::~DebuggerConnectionHandler() {
277 CloseDbgConnection(); 416 CloseDbgConnection();
278 } 417 }
OLDNEW
« no previous file with comments | « runtime/bin/dbg_connection.h ('k') | runtime/platform/c99_support_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698