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

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

Issue 10990089: First step towards support for being able to interrupt a running Dart Isolate (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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_message.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 #include "bin/dbg_connection.h"
6 #include "bin/dbg_message.h"
7 #include "bin/dartutils.h"
8 #include "bin/thread.h"
9 #include "bin/utils.h"
10
11 #include "platform/globals.h"
12 #include "platform/json.h"
13 #include "platform/thread.h"
14 #include "platform/utils.h"
15
16 #include "include/dart_api.h"
17
18 bool MessageParser::IsValidMessage() const {
19 if (buf_length_ == 0) {
20 return false;
21 }
22 dart::JSONReader msg_reader(buf_);
23 return msg_reader.EndOfObject() != NULL;
24 }
25
26
27 int MessageParser::MessageId() const {
28 dart::JSONReader r(buf_);
29 r.Seek("id");
30 if (r.Type() == dart::JSONReader::kInteger) {
31 return atoi(r.ValueChars());
32 } else {
33 return -1;
34 }
35 }
36
37
38 const char* MessageParser::Params() const {
39 dart::JSONReader r(buf_);
40 r.Seek("params");
41 if (r.Type() == dart::JSONReader::kObject) {
42 return r.ValueChars();
43 } else {
44 return NULL;
45 }
46 }
47
48
49 intptr_t MessageParser::GetIntParam(const char* name) const {
50 const char* params = Params();
51 ASSERT(params != NULL);
52 dart::JSONReader r(params);
53 r.Seek(name);
54 ASSERT(r.Type() == dart::JSONReader::kInteger);
55 return strtol(r.ValueChars(), NULL, 10);
56 }
57
58
59 intptr_t MessageParser::GetOptIntParam(const char* name,
60 intptr_t default_val) const {
61 const char* params = Params();
62 ASSERT(params != NULL);
63 dart::JSONReader r(params);
64 r.Seek(name);
65 if (r.Type() == dart::JSONReader::kInteger) {
66 return strtol(r.ValueChars(), NULL, 10);
67 } else {
68 return default_val;
69 }
70 }
71
72
73 static const char* GetStringChars(Dart_Handle str) {
74 ASSERT(Dart_IsString(str));
75 const char* chars;
76 Dart_Handle res = Dart_StringToCString(str, &chars);
77 ASSERT(!Dart_IsError(res));
78 return chars;
79 }
80
81
82 static int GetIntValue(Dart_Handle int_handle) {
83 int64_t int64_val = -1;
84 ASSERT(Dart_IsInteger(int_handle));
85 Dart_Handle res = Dart_IntegerToInt64(int_handle, &int64_val);
86 ASSERT_NOT_ERROR(res);
87 // TODO(hausner): Range check.
88 return int64_val;
89 }
90
91
92 char* MessageParser::GetStringParam(const char* name) const {
93 const char* params = Params();
94 ASSERT(params != NULL);
95 dart::JSONReader pr(params);
96 pr.Seek(name);
97 if (pr.Type() != dart::JSONReader::kString) {
98 return NULL;
99 }
100 intptr_t buflen = pr.ValueLen() + 1;
101 char* param_chars = reinterpret_cast<char*>(malloc(buflen));
102 pr.GetValueChars(param_chars, buflen);
103 // TODO(hausner): Decode escape sequences.
104 return param_chars;
105 }
106
107
108 static void FormatEncodedString(dart::TextBuffer* buf, Dart_Handle str) {
109 intptr_t str_len = 0;
110 Dart_Handle res = Dart_StringLength(str, &str_len);
111 ASSERT_NOT_ERROR(res);
112 uint32_t* codepoints =
113 reinterpret_cast<uint32_t*>(malloc(str_len * sizeof(uint32_t)));
114 ASSERT(codepoints != NULL);
115 intptr_t actual_len = str_len;
116 res = Dart_StringGet32(str, codepoints, &actual_len);
117 ASSERT_NOT_ERROR(res);
118 ASSERT(str_len == actual_len);
119 buf->AddChar('\"');
120 for (int i = 0; i < str_len; i++) {
121 buf->AddEscapedChar(codepoints[i]);
122 }
123 buf->AddChar('\"');
124 free(codepoints);
125 }
126
127
128 static void FormatErrorMsg(dart::TextBuffer* buf, Dart_Handle err) {
129 // TODO(hausner): Turn message into Dart string and
130 // properly encode the message.
131 ASSERT(Dart_IsError(err));
132 const char* msg = Dart_GetError(err);
133 buf->Printf("\"%s\"", msg);
134 }
135
136
137 static void FormatTextualValue(dart::TextBuffer* buf, Dart_Handle object) {
138 Dart_Handle text;
139 if (Dart_IsNull(object)) {
140 text = Dart_Null();
141 } else {
142 Dart_ExceptionPauseInfo savedState = Dart_GetExceptionPauseInfo();
143
144 // TODO(hausner): Check whether recursive/reentrant pauses on exceptions
145 // should be prevented in Debugger::SignalExceptionThrown() instead.
146 if (savedState != kNoPauseOnExceptions) {
147 Dart_Handle res = Dart_SetExceptionPauseInfo(kNoPauseOnExceptions);
148 ASSERT_NOT_ERROR(res);
149 }
150
151 text = Dart_ToString(object);
152
153 if (savedState != kNoPauseOnExceptions) {
154 Dart_Handle res = Dart_SetExceptionPauseInfo(savedState);
155 ASSERT_NOT_ERROR(res);
156 }
157 }
158 buf->Printf("\"text\":");
159 if (Dart_IsNull(text)) {
160 buf->Printf("null");
161 } else if (Dart_IsError(text)) {
162 FormatErrorMsg(buf, text);
163 } else {
164 FormatEncodedString(buf, text);
165 }
166 }
167
168
169 static void FormatValue(dart::TextBuffer* buf, Dart_Handle object) {
170 if (Dart_IsInteger(object)) {
171 buf->Printf("\"kind\":\"integer\",");
172 } else if (Dart_IsString(object)) {
173 buf->Printf("\"kind\":\"string\",");
174 } else if (Dart_IsBoolean(object)) {
175 buf->Printf("\"kind\":\"boolean\",");
176 } else if (Dart_IsList(object)) {
177 intptr_t len = 0;
178 Dart_Handle res = Dart_ListLength(object, &len);
179 ASSERT_NOT_ERROR(res);
180 buf->Printf("\"kind\":\"list\",\"length\":%"Pd",", len);
181 } else {
182 buf->Printf("\"kind\":\"object\",");
183 }
184 FormatTextualValue(buf, object);
185 }
186
187
188 static void FormatValueObj(dart::TextBuffer* buf, Dart_Handle object) {
189 buf->Printf("{");
190 FormatValue(buf, object);
191 buf->Printf("}");
192 }
193
194
195 static void FormatRemoteObj(dart::TextBuffer* buf, Dart_Handle object) {
196 intptr_t obj_id = Dart_CacheObject(object);
197 ASSERT(obj_id >= 0);
198 buf->Printf("{\"objectId\":%"Pd",", obj_id);
199 FormatValue(buf, object);
200 buf->Printf("}");
201 }
202
203
204 static void FormatNamedValue(dart::TextBuffer* buf,
205 Dart_Handle object_name,
206 Dart_Handle object) {
207 ASSERT(Dart_IsString(object_name));
208 buf->Printf("{\"name\":\"%s\",", GetStringChars(object_name));
209 buf->Printf("\"value\":");
210 FormatRemoteObj(buf, object);
211 buf->Printf("}");
212 }
213
214
215 static void FormatNamedValueList(dart::TextBuffer* buf,
216 Dart_Handle obj_list) {
217 ASSERT(Dart_IsList(obj_list));
218 intptr_t list_length = 0;
219 Dart_Handle res = Dart_ListLength(obj_list, &list_length);
220 ASSERT_NOT_ERROR(res);
221 ASSERT(list_length % 2 == 0);
222 buf->Printf("[");
223 for (int i = 0; i + 1 < list_length; i += 2) {
224 Dart_Handle name_handle = Dart_ListGetAt(obj_list, i);
225 ASSERT_NOT_ERROR(name_handle);
226 Dart_Handle value_handle = Dart_ListGetAt(obj_list, i + 1);
227 ASSERT_NOT_ERROR(value_handle);
228 if (i > 0) {
229 buf->Printf(",");
230 }
231 FormatNamedValue(buf, name_handle, value_handle);
232 }
233 buf->Printf("]");
234 }
235
236
237 static const char* FormatClassProps(dart::TextBuffer* buf,
238 intptr_t cls_id) {
239 Dart_Handle name, static_fields;
240 intptr_t super_id = -1;
241 intptr_t library_id = -1;
242 Dart_Handle res =
243 Dart_GetClassInfo(cls_id, &name, &library_id, &super_id, &static_fields);
244 RETURN_IF_ERROR(res);
245 RETURN_IF_ERROR(name);
246 buf->Printf("{\"name\":\"%s\",", GetStringChars(name));
247 if (super_id > 0) {
248 buf->Printf("\"superclassId\":%"Pd",", super_id);
249 }
250 buf->Printf("\"libraryId\":%"Pd",", library_id);
251 RETURN_IF_ERROR(static_fields);
252 buf->Printf("\"fields\":");
253 FormatNamedValueList(buf, static_fields);
254 buf->Printf("}");
255 return NULL;
256 }
257
258
259 static const char* FormatLibraryProps(dart::TextBuffer* buf,
260 intptr_t lib_id) {
261 Dart_Handle url = Dart_GetLibraryURL(lib_id);
262 RETURN_IF_ERROR(url);
263 buf->Printf("{\"url\":");
264 FormatEncodedString(buf, url);
265
266 // Whether debugging is enabled.
267 bool is_debuggable = false;
268 Dart_Handle res = Dart_GetLibraryDebuggable(lib_id, &is_debuggable);
269 RETURN_IF_ERROR(res);
270 buf->Printf(",\"debuggingEnabled\":%s",
271 is_debuggable ? "\"true\"" : "\"false\"");
272
273 // Imports and prefixes.
274 Dart_Handle import_list = Dart_GetLibraryImports(lib_id);
275 RETURN_IF_ERROR(import_list);
276 ASSERT(Dart_IsList(import_list));
277 intptr_t list_length = 0;
278 res = Dart_ListLength(import_list, &list_length);
279 RETURN_IF_ERROR(res);
280 buf->Printf(",\"imports\":[");
281 for (int i = 0; i + 1 < list_length; i += 2) {
282 Dart_Handle lib_id = Dart_ListGetAt(import_list, i + 1);
283 ASSERT_NOT_ERROR(lib_id);
284 buf->Printf("%s{\"libraryId\":%d,",
285 (i > 0) ? ",": "",
286 GetIntValue(lib_id));
287
288 Dart_Handle name = Dart_ListGetAt(import_list, i);
289 ASSERT_NOT_ERROR(name);
290 buf->Printf("\"prefix\":\"%s\"}",
291 Dart_IsNull(name) ? "" : GetStringChars(name));
292 }
293 buf->Printf("],");
294
295 // Global variables in the library.
296 Dart_Handle global_vars = Dart_GetLibraryFields(lib_id);
297 RETURN_IF_ERROR(global_vars);
298 buf->Printf("\"globals\":");
299 FormatNamedValueList(buf, global_vars);
300 buf->Printf("}");
301 return NULL;
302 }
303
304
305 static const char* FormatObjProps(dart::TextBuffer* buf,
306 Dart_Handle object) {
307 intptr_t class_id;
308 if (Dart_IsNull(object)) {
309 buf->Printf("{\"classId\":-1,\"fields\":[]}");
310 return NULL;
311 }
312 Dart_Handle res = Dart_GetObjClassId(object, &class_id);
313 RETURN_IF_ERROR(res);
314 buf->Printf("{\"classId\": %"Pd",", class_id);
315 buf->Printf("\"kind\":\"object\",\"fields\":");
316 Dart_Handle fields = Dart_GetInstanceFields(object);
317 RETURN_IF_ERROR(fields);
318 FormatNamedValueList(buf, fields);
319 buf->Printf("}");
320 return NULL;
321 }
322
323
324 static const char* FormatListSlice(dart::TextBuffer* buf,
325 Dart_Handle list,
326 intptr_t list_length,
327 intptr_t index,
328 intptr_t slice_length) {
329 intptr_t end_index = index + slice_length;
330 ASSERT(end_index <= list_length);
331 buf->Printf("{\"index\":%"Pd",", index);
332 buf->Printf("\"length\":%"Pd",", slice_length);
333 buf->Printf("\"elements\":[");
334 for (intptr_t i = index; i < end_index; i++) {
335 Dart_Handle value = Dart_ListGetAt(list, i);
336 if (i > index) {
337 buf->Printf(",");
338 }
339 FormatValueObj(buf, value);
340 }
341 buf->Printf("]}");
342 return NULL;
343 }
344
345
346 static void FormatCallFrames(dart::TextBuffer* msg, Dart_StackTrace trace) {
347 intptr_t trace_len = 0;
348 Dart_Handle res = Dart_StackTraceLength(trace, &trace_len);
349 ASSERT_NOT_ERROR(res);
350 msg->Printf("\"callFrames\" : [ ");
351 for (int i = 0; i < trace_len; i++) {
352 Dart_ActivationFrame frame;
353 res = Dart_GetActivationFrame(trace, i, &frame);
354 ASSERT_NOT_ERROR(res);
355 Dart_Handle func_name;
356 Dart_Handle script_url;
357 intptr_t line_number = 0;
358 intptr_t library_id = 0;
359 res = Dart_ActivationFrameInfo(
360 frame, &func_name, &script_url, &line_number, &library_id);
361 ASSERT_NOT_ERROR(res);
362 ASSERT(Dart_IsString(func_name));
363 msg->Printf("%s{\"functionName\":", (i > 0) ? "," : "");
364 FormatEncodedString(msg, func_name);
365 msg->Printf(",\"libraryId\": %"Pd",", library_id);
366
367 ASSERT(Dart_IsString(script_url));
368 msg->Printf("\"location\": { \"url\":");
369 FormatEncodedString(msg, script_url);
370 msg->Printf(",\"lineNumber\":%"Pd"},", line_number);
371
372 Dart_Handle locals = Dart_GetLocalVariables(frame);
373 ASSERT_NOT_ERROR(locals);
374 msg->Printf("\"locals\":");
375 FormatNamedValueList(msg, locals);
376 msg->Printf("}");
377 }
378 msg->Printf("]");
379 }
380
381
382 typedef bool (*CommandHandler)(DbgMessage* msg);
383
384 struct JSONDebuggerCommand {
385 const char* cmd_string;
386 CommandHandler handler_function;
387 };
388
389
390 static JSONDebuggerCommand debugger_commands[] = {
391 { "resume", DbgMessage::HandleResumeCmd },
392 { "stepInto", DbgMessage::HandleStepIntoCmd },
393 { "stepOut", DbgMessage::HandleStepOutCmd },
394 { "stepOver", DbgMessage::HandleStepOverCmd },
395 { "getLibraries", DbgMessage::HandleGetLibrariesCmd },
396 { "getClassProperties", DbgMessage::HandleGetClassPropsCmd },
397 { "getLibraryProperties", DbgMessage::HandleGetLibPropsCmd },
398 { "setLibraryProperties", DbgMessage::HandleSetLibPropsCmd },
399 { "getObjectProperties", DbgMessage::HandleGetObjPropsCmd },
400 { "getListElements", DbgMessage::HandleGetListCmd },
401 { "getGlobalVariables", DbgMessage::HandleGetGlobalsCmd },
402 { "getScriptURLs", DbgMessage::HandleGetScriptURLsCmd },
403 { "getScriptSource", DbgMessage::HandleGetSourceCmd },
404 { "getStackTrace", DbgMessage::HandleGetStackTraceCmd },
405 { "setBreakpoint", DbgMessage::HandleSetBpCmd },
406 { "setPauseOnException", DbgMessage::HandlePauseOnExcCmd },
407 { "removeBreakpoint", DbgMessage::HandleRemBpCmd },
408 { NULL, NULL }
409 };
410
411
412 bool DbgMessage::HandleMessage() {
413 // Dispatch to the appropriate handler for the command.
414 int max_index = (sizeof(debugger_commands) / sizeof(JSONDebuggerCommand));
415 ASSERT(cmd_idx_ < max_index);
416 return (*debugger_commands[cmd_idx_].handler_function)(this);
417 }
418
419
420 void DbgMessage::SendReply(dart::TextBuffer* reply) {
421 DebuggerConnectionHandler::SendMsg(debug_fd(), reply);
422 }
423
424
425 void DbgMessage::SendErrorReply(int msg_id, const char* err_msg) {
426 DebuggerConnectionHandler::SendError(debug_fd(), msg_id, err_msg);
427 }
428
429
430 bool DbgMessage::HandleResumeCmd(DbgMessage* in_msg) {
431 ASSERT(in_msg != NULL);
432 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
433 int msg_id = msg_parser.MessageId();
434 dart::TextBuffer msg(64);
435 msg.Printf("{ \"id\": %d }", msg_id);
436 in_msg->SendReply(&msg);
437 return true;
438 }
439
440
441 bool DbgMessage::HandleStepIntoCmd(DbgMessage* in_msg) {
442 Dart_Handle res = Dart_SetStepInto();
443 ASSERT_NOT_ERROR(res);
444 return HandleResumeCmd(in_msg);
445 }
446
447
448 bool DbgMessage::HandleStepOutCmd(DbgMessage* in_msg) {
449 Dart_Handle res = Dart_SetStepOut();
450 ASSERT_NOT_ERROR(res);
451 return HandleResumeCmd(in_msg);
452 }
453
454
455 bool DbgMessage::HandleStepOverCmd(DbgMessage* in_msg) {
456 Dart_Handle res = Dart_SetStepOver();
457 ASSERT_NOT_ERROR(res);
458 return HandleResumeCmd(in_msg);
459 }
460
461
462 bool DbgMessage::HandleGetLibrariesCmd(DbgMessage* in_msg) {
463 ASSERT(in_msg != NULL);
464 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
465 int msg_id = msg_parser.MessageId();
466 dart::TextBuffer msg(64);
467 msg.Printf("{ \"id\": %d, \"result\": { \"libraries\": [", msg_id);
468 Dart_Handle lib_ids = Dart_GetLibraryIds();
469 ASSERT_NOT_ERROR(lib_ids);
470 intptr_t num_libs;
471 Dart_Handle res = Dart_ListLength(lib_ids, &num_libs);
472 ASSERT_NOT_ERROR(res);
473 for (int i = 0; i < num_libs; i++) {
474 Dart_Handle lib_id_handle = Dart_ListGetAt(lib_ids, i);
475 ASSERT(Dart_IsInteger(lib_id_handle));
476 int lib_id = GetIntValue(lib_id_handle);
477 Dart_Handle lib_url = Dart_GetLibraryURL(lib_id);
478 ASSERT_NOT_ERROR(lib_url);
479 ASSERT(Dart_IsString(lib_url));
480 msg.Printf("%s{\"id\":%d,\"url\":", (i == 0) ? "" : ", ", lib_id);
481 FormatEncodedString(&msg, lib_url);
482 msg.Printf("}");
483 }
484 msg.Printf("]}}");
485 in_msg->SendReply(&msg);
486 return false;
487 }
488
489
490 bool DbgMessage::HandleGetClassPropsCmd(DbgMessage* in_msg) {
491 ASSERT(in_msg != NULL);
492 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
493 int msg_id = msg_parser.MessageId();
494 intptr_t cls_id = msg_parser.GetIntParam("classId");
495 dart::TextBuffer msg(64);
496 msg.Printf("{\"id\":%d, \"result\":", msg_id);
497 const char* err = FormatClassProps(&msg, cls_id);
498 if (err != NULL) {
499 in_msg->SendErrorReply(msg_id, err);
500 return false;
501 }
502 msg.Printf("}");
503 in_msg->SendReply(&msg);
504 return false;
505 }
506
507
508 bool DbgMessage::HandleGetLibPropsCmd(DbgMessage* in_msg) {
509 ASSERT(in_msg != NULL);
510 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
511 int msg_id = msg_parser.MessageId();
512 intptr_t lib_id = msg_parser.GetIntParam("libraryId");
513 dart::TextBuffer msg(64);
514 msg.Printf("{\"id\":%d, \"result\":", msg_id);
515 const char* err = FormatLibraryProps(&msg, lib_id);
516 if (err != NULL) {
517 in_msg->SendErrorReply(msg_id, err);
518 return false;
519 }
520 msg.Printf("}");
521 in_msg->SendReply(&msg);
522 return false;
523 }
524
525
526 bool DbgMessage::HandleSetLibPropsCmd(DbgMessage* in_msg) {
527 ASSERT(in_msg != NULL);
528 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
529 int msg_id = msg_parser.MessageId();
530 intptr_t lib_id = msg_parser.GetIntParam("libraryId");
531 const char* enable_request = msg_parser.GetStringParam("debuggingEnabled");
532 bool enable;
533 if (strcmp(enable_request, "true") == 0) {
534 enable = true;
535 } else if (strcmp(enable_request, "false") == 0) {
536 enable = false;
537 } else {
538 in_msg->SendErrorReply(msg_id, "illegal argument for 'debuggingEnabled'");
539 return false;
540 }
541 Dart_Handle res = Dart_SetLibraryDebuggable(lib_id, enable);
542 if (Dart_IsError(res)) {
543 in_msg->SendErrorReply(msg_id, Dart_GetError(res));
544 return false;
545 }
546 bool enabled = false;
547 res = Dart_GetLibraryDebuggable(lib_id, &enabled);
548 if (Dart_IsError(res)) {
549 in_msg->SendErrorReply(msg_id, Dart_GetError(res));
550 return false;
551 }
552 dart::TextBuffer msg(64);
553 msg.Printf("{\"id\":%d, \"result\": {\"debuggingEnabled\": \"%s\"}}",
554 msg_id,
555 enabled ? "true" : "false");
556 in_msg->SendReply(&msg);
557 return false;
558 }
559
560
561 bool DbgMessage::HandleGetObjPropsCmd(DbgMessage* in_msg) {
562 ASSERT(in_msg != NULL);
563 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
564 int msg_id = msg_parser.MessageId();
565 intptr_t obj_id = msg_parser.GetIntParam("objectId");
566 Dart_Handle obj = Dart_GetCachedObject(obj_id);
567 if (Dart_IsError(obj)) {
568 in_msg->SendErrorReply(msg_id, Dart_GetError(obj));
569 return false;
570 }
571 dart::TextBuffer msg(64);
572 msg.Printf("{\"id\":%d, \"result\":", msg_id);
573 const char* err = FormatObjProps(&msg, obj);
574 if (err != NULL) {
575 in_msg->SendErrorReply(msg_id, err);
576 return false;
577 }
578 msg.Printf("}");
579 in_msg->SendReply(&msg);
580 return false;
581 }
582
583
584 bool DbgMessage::HandleGetListCmd(DbgMessage* in_msg) {
585 const intptr_t kDefaultSliceLength = 100;
586 ASSERT(in_msg != NULL);
587 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
588 int msg_id = msg_parser.MessageId();
589 intptr_t obj_id = msg_parser.GetIntParam("objectId");
590 Dart_Handle list = Dart_GetCachedObject(obj_id);
591 if (Dart_IsError(list)) {
592 in_msg->SendErrorReply(msg_id, Dart_GetError(list));
593 return false;
594 }
595 if (!Dart_IsList(list)) {
596 in_msg->SendErrorReply(msg_id, "object is not a list");
597 return false;
598 }
599 intptr_t list_length = 0;
600 Dart_Handle res = Dart_ListLength(list, &list_length);
601 if (Dart_IsError(res)) {
602 in_msg->SendErrorReply(msg_id, Dart_GetError(res));
603 return false;
604 }
605
606 intptr_t index = msg_parser.GetIntParam("index");
607 if (index < 0) {
608 index = 0;
609 } else if (index > list_length) {
610 index = list_length;
611 }
612
613 // If no slice length is given, get only one element. If slice length
614 // is given as 0, get entire list.
615 intptr_t slice_length = msg_parser.GetOptIntParam("length", 1);
616 if (slice_length == 0) {
617 slice_length = list_length - index;
618 }
619 if ((index + slice_length) > list_length) {
620 slice_length = list_length - index;
621 }
622 ASSERT(slice_length >= 0);
623 if (slice_length > kDefaultSliceLength) {
624 slice_length = kDefaultSliceLength;
625 }
626 dart::TextBuffer msg(64);
627 msg.Printf("{\"id\":%d, \"result\":", msg_id);
628 if (slice_length == 1) {
629 Dart_Handle value = Dart_ListGetAt(list, index);
630 FormatRemoteObj(&msg, value);
631 } else {
632 FormatListSlice(&msg, list, list_length, index, slice_length);
633 }
634 msg.Printf("}");
635 in_msg->SendReply(&msg);
636 return false;
637 }
638
639
640 bool DbgMessage::HandleGetGlobalsCmd(DbgMessage* in_msg) {
641 ASSERT(in_msg != NULL);
642 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
643 int msg_id = msg_parser.MessageId();
644 intptr_t lib_id = msg_parser.GetIntParam("libraryId");
645 dart::TextBuffer msg(64);
646 msg.Printf("{\"id\":%d, \"result\": { \"globals\":", msg_id);
647 Dart_Handle globals = Dart_GetGlobalVariables(lib_id);
648 ASSERT_NOT_ERROR(globals);
649 FormatNamedValueList(&msg, globals);
650 msg.Printf("}}");
651 in_msg->SendReply(&msg);
652 return false;
653 }
654
655
656 bool DbgMessage::HandleGetScriptURLsCmd(DbgMessage* in_msg) {
657 ASSERT(in_msg != NULL);
658 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
659 int msg_id = msg_parser.MessageId();
660 dart::TextBuffer msg(64);
661 intptr_t lib_id = msg_parser.GetIntParam("libraryId");
662 Dart_Handle lib_url = Dart_GetLibraryURL(lib_id);
663 ASSERT_NOT_ERROR(lib_url);
664 Dart_Handle urls = Dart_GetScriptURLs(lib_url);
665 if (Dart_IsError(urls)) {
666 in_msg->SendErrorReply(msg_id, Dart_GetError(urls));
667 return false;
668 }
669 ASSERT(Dart_IsList(urls));
670 intptr_t num_urls = 0;
671 Dart_ListLength(urls, &num_urls);
672 msg.Printf("{ \"id\": %d, ", msg_id);
673 msg.Printf("\"result\": { \"urls\": [");
674 for (int i = 0; i < num_urls; i++) {
675 Dart_Handle script_url = Dart_ListGetAt(urls, i);
676 if (i > 0) {
677 msg.Printf(",");
678 }
679 FormatEncodedString(&msg, script_url);
680 }
681 msg.Printf("]}}");
682 in_msg->SendReply(&msg);
683 return false;
684 }
685
686
687 bool DbgMessage::HandleGetSourceCmd(DbgMessage* in_msg) {
688 ASSERT(in_msg != NULL);
689 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
690 int msg_id = msg_parser.MessageId();
691 dart::TextBuffer msg(64);
692 intptr_t lib_id = msg_parser.GetIntParam("libraryId");
693 char* url_chars = msg_parser.GetStringParam("url");
694 ASSERT(url_chars != NULL);
695 Dart_Handle url = Dart_NewString(url_chars);
696 ASSERT_NOT_ERROR(url);
697 free(url_chars);
698 url_chars = NULL;
699 Dart_Handle source = Dart_ScriptGetSource(lib_id, url);
700 if (Dart_IsError(source)) {
701 in_msg->SendErrorReply(msg_id, Dart_GetError(source));
702 return false;
703 }
704 msg.Printf("{ \"id\": %d, ", msg_id);
705 msg.Printf("\"result\": { \"text\": ");
706 FormatEncodedString(&msg, source);
707 msg.Printf("}}");
708 in_msg->SendReply(&msg);
709 return false;
710 }
711
712
713 bool DbgMessage::HandleGetStackTraceCmd(DbgMessage* in_msg) {
714 ASSERT(in_msg != NULL);
715 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
716 int msg_id = msg_parser.MessageId();
717 Dart_StackTrace trace;
718 Dart_Handle res = Dart_GetStackTrace(&trace);
719 ASSERT_NOT_ERROR(res);
720 dart::TextBuffer msg(128);
721 msg.Printf("{ \"id\": %d, \"result\": {", msg_id);
722 FormatCallFrames(&msg, trace);
723 msg.Printf("}}");
724 in_msg->SendReply(&msg);
725 return false;
726 }
727
728
729 bool DbgMessage::HandleSetBpCmd(DbgMessage* in_msg) {
730 ASSERT(in_msg != NULL);
731 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
732 int msg_id = msg_parser.MessageId();
733 char* url_chars = msg_parser.GetStringParam("url");
734 ASSERT(url_chars != NULL);
735 Dart_Handle url = Dart_NewString(url_chars);
736 ASSERT_NOT_ERROR(url);
737 free(url_chars);
738 url_chars = NULL;
739 intptr_t line_number = msg_parser.GetIntParam("line");
740 Dart_Handle bp_id = Dart_SetBreakpoint(url, line_number);
741 if (Dart_IsError(bp_id)) {
742 in_msg->SendErrorReply(msg_id, Dart_GetError(bp_id));
743 return false;
744 }
745 ASSERT(Dart_IsInteger(bp_id));
746 uint64_t bp_id_value;
747 Dart_Handle res = Dart_IntegerToUint64(bp_id, &bp_id_value);
748 ASSERT_NOT_ERROR(res);
749 dart::TextBuffer msg(64);
750 msg.Printf("{ \"id\": %d, \"result\": { \"breakpointId\": %"Pu64" }}",
751 msg_id, bp_id_value);
752 in_msg->SendReply(&msg);
753 return false;
754 }
755
756
757 bool DbgMessage::HandlePauseOnExcCmd(DbgMessage* in_msg) {
758 ASSERT(in_msg != NULL);
759 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
760 int msg_id = msg_parser.MessageId();
761 char* exc_chars = msg_parser.GetStringParam("exceptions");
762 Dart_ExceptionPauseInfo info = kNoPauseOnExceptions;
763 if (strcmp(exc_chars, "none") == 0) {
764 info = kNoPauseOnExceptions;
765 } else if (strcmp(exc_chars, "all") == 0) {
766 info = kPauseOnAllExceptions;
767 } else if (strcmp(exc_chars, "unhandled") == 0) {
768 info = kPauseOnUnhandledExceptions;
769 } else {
770 in_msg->SendErrorReply(msg_id, "illegal value for parameter 'exceptions'");
771 return false;
772 }
773 Dart_Handle res = Dart_SetExceptionPauseInfo(info);
774 ASSERT_NOT_ERROR(res);
775 dart::TextBuffer msg(32);
776 msg.Printf("{ \"id\": %d }", msg_id);
777 in_msg->SendReply(&msg);
778 return false;
779 }
780
781
782 bool DbgMessage::HandleRemBpCmd(DbgMessage* in_msg) {
783 ASSERT(in_msg != NULL);
784 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
785 int msg_id = msg_parser.MessageId();
786 int bpt_id = msg_parser.GetIntParam("breakpointId");
787 Dart_Handle res = Dart_RemoveBreakpoint(bpt_id);
788 if (Dart_IsError(res)) {
789 in_msg->SendErrorReply(msg_id, Dart_GetError(res));
790 return false;
791 }
792 dart::TextBuffer msg(32);
793 msg.Printf("{ \"id\": %d }", msg_id);
794 in_msg->SendReply(&msg);
795 return false;
796 }
797
798
799 void DbgMessageQueue::AddMessage(int32_t cmd_idx,
800 const char* start,
801 const char* end,
802 int debug_fd) {
803 if ((end > start) && ((end - start) < kMaxUint32)) {
804 MonitorLocker ml(&msg_queue_lock_);
805 DbgMessage* msg = new DbgMessage(cmd_idx, start, end, debug_fd);
806 if (msglist_head_ == NULL) {
807 ASSERT(msglist_tail_ == NULL);
808 msglist_head_ = msg;
809 msglist_tail_ = msg;
810 ml.Notify();
811 } else {
812 ASSERT(msglist_tail_ != NULL);
813 msglist_tail_->set_next(msg);
814 msglist_tail_ = msg;
815 }
816 }
817 }
818
819
820 void DbgMessageQueue::HandleMessages() {
821 bool resume_requested = false;
822 MonitorLocker ml(&msg_queue_lock_);
823 is_running_ = false;
824 while (!resume_requested) {
825 while (msglist_head_ == NULL) {
826 ASSERT(msglist_tail_ == NULL);
827 dart::Monitor::WaitResult res = ml.Wait(); // Wait for debugger commands.
828 ASSERT(res == dart::Monitor::kNotified);
829 }
830 while (msglist_head_ != NULL && !resume_requested) {
831 ASSERT(msglist_tail_ != NULL);
832 DbgMessage* msg = msglist_head_;
833 msglist_head_ = msglist_head_->next();
834 resume_requested = msg->HandleMessage();
835 delete msg;
836 }
837 if (msglist_head_ == NULL) {
838 msglist_tail_ = NULL;
839 }
840 }
841 is_running_ = true;
842 }
843
844
845 void DbgMessageQueue::QueueOutputMsg(dart::TextBuffer* msg) {
846 queued_output_messages_.Printf("%s", msg->buf());
847 }
848
849
850 void DbgMessageQueue::SendQueuedMsgs() {
851 if (queued_output_messages_.length() > 0) {
852 DebuggerConnectionHandler::BroadcastMsg(&queued_output_messages_);
853 queued_output_messages_.Clear();
854 }
855 }
856
857
858 void DbgMessageQueue::SendBreakpointEvent(Dart_StackTrace trace) {
859 dart::TextBuffer msg(128);
860 msg.Printf("{ \"event\": \"paused\", \"params\": { ");
861 msg.Printf("\"reason\": \"breakpoint\", ");
862 FormatCallFrames(&msg, trace);
863 msg.Printf("}}");
864 DebuggerConnectionHandler::BroadcastMsg(&msg);
865 }
866
867
868 void DbgMessageQueue::SendExceptionEvent(Dart_Handle exception,
869 Dart_StackTrace stack_trace) {
870 intptr_t exception_id = Dart_CacheObject(exception);
871 ASSERT(exception_id >= 0);
872 dart::TextBuffer msg(128);
873 msg.Printf("{ \"event\": \"paused\", \"params\": {");
874 msg.Printf("\"reason\": \"exception\", ");
875 msg.Printf("\"exception\":");
876 FormatRemoteObj(&msg, exception);
877 msg.Printf(", ");
878 FormatCallFrames(&msg, stack_trace);
879 msg.Printf("}}");
880 DebuggerConnectionHandler::BroadcastMsg(&msg);
881 }
882
883
884 // TODO(asiva): Get rid of this static variable one we have a means
885 // for associating an isolate with a debugger message queue object.
886 static DbgMessageQueue* message_queue = NULL;
887
888
889 void DbgMessageQueue::Initialize() {
890 // TODO(asiva): Need to setup a message queue when an Isolate is created.
891 // For now we use a static message queue object as we are only supporting
892 // debugging of a single isolate.
893 message_queue = new DbgMessageQueue();
894
895 // Setup handlers for isolate events, breakpoints, exceptions and
896 // delayed breakpoints.
897 Dart_SetIsolateEventHandler(IsolateEventHandler);
898 Dart_SetBreakpointHandler(BreakpointHandler);
899 Dart_SetBreakpointResolvedHandler(BptResolvedHandler);
900 Dart_SetExceptionThrownHandler(ExceptionThrownHandler);
901 }
902
903
904 int32_t DbgMessageQueue::LookupIsolateCommand(const char* buf,
905 int32_t buflen) {
906 // Check if we have a isolate specific debugger command.
907 int32_t i = 0;
908 while (debugger_commands[i].cmd_string != NULL) {
909 if (strncmp(buf, debugger_commands[i].cmd_string, buflen) == 0) {
910 return i;
911 }
912 i++;
913 }
914 return kInvalidCommand;
915 }
916
917
918 DbgMessageQueue* DbgMessageQueue::GetIsolateMessageQueue(Dart_Isolate isolate) {
919 // TODO(asiva): Return a message queue corresponding to the isolate.
920 // For now we use a static message queue object as we are only supporting
921 // debugging of a single isolate.
922 return message_queue;
923 }
924
925
926 void DbgMessageQueue::BptResolvedHandler(intptr_t bp_id,
927 Dart_Handle url,
928 intptr_t line_number) {
929 Dart_EnterScope();
930 dart::TextBuffer msg(128);
931 msg.Printf("{ \"event\": \"breakpointResolved\", \"params\": {");
932 msg.Printf("\"breakpointId\": %"Pd", \"url\":", bp_id);
933 FormatEncodedString(&msg, url);
934 msg.Printf(",\"line\": %"Pd" }}", line_number);
935 DbgMessageQueue* msg_queue = GetIsolateMessageQueue(Dart_CurrentIsolate());
936 ASSERT(msg_queue != NULL);
937 msg_queue->QueueOutputMsg(&msg);
938 Dart_ExitScope();
939 }
940
941
942 void DbgMessageQueue::BreakpointHandler(Dart_Breakpoint bpt,
943 Dart_StackTrace trace) {
944 DebuggerConnectionHandler::WaitForConnection();
945 Dart_EnterScope();
946 DbgMessageQueue* msg_queue = GetIsolateMessageQueue(Dart_CurrentIsolate());
947 ASSERT(msg_queue != NULL);
948 msg_queue->SendQueuedMsgs();
949 msg_queue->SendBreakpointEvent(trace);
950 msg_queue->HandleMessages();
951 Dart_ExitScope();
952 }
953
954
955 void DbgMessageQueue::ExceptionThrownHandler(Dart_Handle exception,
956 Dart_StackTrace stack_trace) {
957 DebuggerConnectionHandler::WaitForConnection();
958 Dart_EnterScope();
959 DbgMessageQueue* msg_queue = GetIsolateMessageQueue(Dart_CurrentIsolate());
960 ASSERT(msg_queue != NULL);
961 msg_queue->SendQueuedMsgs();
962 msg_queue->SendExceptionEvent(exception, stack_trace);
963 msg_queue->HandleMessages();
964 Dart_ExitScope();
965 }
966
967
968 void DbgMessageQueue::IsolateEventHandler(Dart_Isolate isolate,
969 Dart_IsolateEvent kind) {
970 DebuggerConnectionHandler::WaitForConnection();
971 #if 0
972 if (kind == kCreated) {
973 printf("Isolate created %p\n", isolate);
974 } else if (kind == kInterrupted) {
975 printf("Isolate interrupted %p\n", isolate);
976 } else if (kind == kShutdown) {
977 printf("Isolate shutdown %p\n", isolate);
978 }
979 #endif
980 }
OLDNEW
« no previous file with comments | « runtime/bin/dbg_message.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698