| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "vm/debugger.h" | 5 #include "vm/debugger.h" |
| 6 #include "vm/heap_histogram.h" | 6 #include "vm/heap_histogram.h" |
| 7 #include "vm/isolate.h" | 7 #include "vm/isolate.h" |
| 8 #include "vm/message.h" | 8 #include "vm/message.h" |
| 9 #include "vm/object.h" | 9 #include "vm/object.h" |
| 10 #include "vm/object_id_ring.h" | 10 #include "vm/object_id_ring.h" |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 } | 133 } |
| 134 { | 134 { |
| 135 JSONArray jsarr(&jsobj, "option_values"); | 135 JSONArray jsarr(&jsobj, "option_values"); |
| 136 for (intptr_t i = 0; i < js->num_options(); i++) { | 136 for (intptr_t i = 0; i < js->num_options(); i++) { |
| 137 jsarr.AddValue(js->GetOptionValue(i)); | 137 jsarr.AddValue(js->GetOptionValue(i)); |
| 138 } | 138 } |
| 139 } | 139 } |
| 140 } | 140 } |
| 141 | 141 |
| 142 | 142 |
| 143 static void PrintCollectionErrorResponse(const char* collection_name, | |
| 144 JSONStream* js) { | |
| 145 JSONObject jsobj(js); | |
| 146 jsobj.AddProperty("type", "error"); | |
| 147 jsobj.AddPropertyF("text", "Must specify collection object id: /%s/id", | |
| 148 collection_name); | |
| 149 } | |
| 150 | |
| 151 | |
| 152 static void PrintGenericError(JSONStream* js) { | 143 static void PrintGenericError(JSONStream* js) { |
| 153 JSONObject jsobj(js); | 144 JSONObject jsobj(js); |
| 154 jsobj.AddProperty("type", "error"); | 145 jsobj.AddProperty("type", "Error"); |
| 155 jsobj.AddProperty("text", "Invalid request."); | 146 jsobj.AddProperty("text", "Invalid request."); |
| 156 PrintArgumentsAndOptions(jsobj, js); | 147 PrintArgumentsAndOptions(jsobj, js); |
| 157 } | 148 } |
| 158 | 149 |
| 150 |
| 151 static void PrintError(JSONStream* js, const char* format, ...) { |
| 152 Isolate* isolate = Isolate::Current(); |
| 153 |
| 154 va_list args; |
| 155 va_start(args, format); |
| 156 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
| 157 va_end(args); |
| 158 |
| 159 char* buffer = isolate->current_zone()->Alloc<char>(len + 1); |
| 160 va_list args2; |
| 161 va_start(args2, format); |
| 162 OS::VSNPrint(buffer, (len + 1), format, args2); |
| 163 va_end(args2); |
| 164 |
| 165 JSONObject jsobj(js); |
| 166 jsobj.AddProperty("type", "Error"); |
| 167 jsobj.AddProperty("text", buffer); |
| 168 PrintArgumentsAndOptions(jsobj, js); |
| 169 } |
| 170 |
| 159 | 171 |
| 160 static void HandleName(Isolate* isolate, JSONStream* js) { | 172 static void HandleName(Isolate* isolate, JSONStream* js) { |
| 161 JSONObject jsobj(js); | 173 JSONObject jsobj(js); |
| 162 jsobj.AddProperty("type", "IsolateName"); | 174 jsobj.AddProperty("type", "IsolateName"); |
| 163 jsobj.AddProperty("id", static_cast<intptr_t>(isolate->main_port())); | 175 jsobj.AddProperty("id", static_cast<intptr_t>(isolate->main_port())); |
| 164 jsobj.AddProperty("name", isolate->name()); | 176 jsobj.AddProperty("name", isolate->name()); |
| 165 } | 177 } |
| 166 | 178 |
| 167 | 179 |
| 168 static void HandleStackTrace(Isolate* isolate, JSONStream* js) { | 180 static void HandleStackTrace(Isolate* isolate, JSONStream* js) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 184 jsobj.AddProperty("function", frame->function()); | 196 jsobj.AddProperty("function", frame->function()); |
| 185 jsobj.AddProperty("code", frame->code()); | 197 jsobj.AddProperty("code", frame->code()); |
| 186 } | 198 } |
| 187 } | 199 } |
| 188 | 200 |
| 189 | 201 |
| 190 static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) { | 202 static void HandleObjectHistogram(Isolate* isolate, JSONStream* js) { |
| 191 ObjectHistogram* histogram = Isolate::Current()->object_histogram(); | 203 ObjectHistogram* histogram = Isolate::Current()->object_histogram(); |
| 192 if (histogram == NULL) { | 204 if (histogram == NULL) { |
| 193 JSONObject jsobj(js); | 205 JSONObject jsobj(js); |
| 194 jsobj.AddProperty("type", "error"); | 206 jsobj.AddProperty("type", "Error"); |
| 195 jsobj.AddProperty("text", "Run with --print_object_histogram"); | 207 jsobj.AddProperty("text", "Run with --print_object_histogram"); |
| 196 return; | 208 return; |
| 197 } | 209 } |
| 198 histogram->PrintToJSONStream(js); | 210 histogram->PrintToJSONStream(js); |
| 199 } | 211 } |
| 200 | 212 |
| 201 | 213 |
| 202 static void HandleEcho(Isolate* isolate, JSONStream* js) { | 214 static void HandleEcho(Isolate* isolate, JSONStream* js) { |
| 203 JSONObject jsobj(js); | 215 JSONObject jsobj(js); |
| 204 jsobj.AddProperty("type", "message"); | 216 jsobj.AddProperty("type", "message"); |
| 205 PrintArgumentsAndOptions(jsobj, js); | 217 PrintArgumentsAndOptions(jsobj, js); |
| 206 } | 218 } |
| 207 | 219 |
| 208 | 220 |
| 209 // Print an error message if there is no ID argument. | 221 // Print an error message if there is no ID argument. |
| 210 #define REQUIRE_COLLECTION_ID(collection) \ | 222 #define REQUIRE_COLLECTION_ID(collection) \ |
| 211 if (js->num_arguments() == 1) { \ | 223 if (js->num_arguments() == 1) { \ |
| 212 PrintCollectionErrorResponse(collection, js); \ | 224 PrintError(js, "Must specify collection object id: /%s/id", collection); \ |
| 213 return; \ | 225 return; \ |
| 214 } | 226 } |
| 215 | 227 |
| 216 | 228 |
| 217 static void HandleClasses(Isolate* isolate, JSONStream* js) { | 229 static void HandleClasses(Isolate* isolate, JSONStream* js) { |
| 218 if (js->num_arguments() == 1) { | 230 if (js->num_arguments() == 1) { |
| 219 ClassTable* table = isolate->class_table(); | 231 ClassTable* table = isolate->class_table(); |
| 220 table->PrintToJSONStream(js); | 232 table->PrintToJSONStream(js); |
| 221 return; | 233 return; |
| 222 } | 234 } |
| 223 ASSERT(js->num_arguments() >= 2); | 235 ASSERT(js->num_arguments() >= 2); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 247 REQUIRE_COLLECTION_ID("objects"); | 259 REQUIRE_COLLECTION_ID("objects"); |
| 248 ASSERT(js->num_arguments() >= 2); | 260 ASSERT(js->num_arguments() >= 2); |
| 249 ObjectIdRing* ring = isolate->object_id_ring(); | 261 ObjectIdRing* ring = isolate->object_id_ring(); |
| 250 ASSERT(ring != NULL); | 262 ASSERT(ring != NULL); |
| 251 intptr_t id = atoi(js->GetArgument(1)); | 263 intptr_t id = atoi(js->GetArgument(1)); |
| 252 Object& obj = Object::Handle(ring->GetObjectForId(id)); | 264 Object& obj = Object::Handle(ring->GetObjectForId(id)); |
| 253 obj.PrintToJSONStream(js, false); | 265 obj.PrintToJSONStream(js, false); |
| 254 } | 266 } |
| 255 | 267 |
| 256 | 268 |
| 269 static void HandleDebug(Isolate* isolate, JSONStream* js) { |
| 270 if (js->num_arguments() == 1) { |
| 271 PrintError(js, "Must specify a subcommand"); |
| 272 return; |
| 273 } |
| 274 const char* command = js->GetArgument(1); |
| 275 if (!strcmp(command, "breakpoints")) { |
| 276 if (js->num_arguments() == 2) { |
| 277 // Print breakpoint list. |
| 278 JSONObject jsobj(js); |
| 279 jsobj.AddProperty("type", "BreakpointList"); |
| 280 JSONArray jsarr(&jsobj, "breakpoints"); |
| 281 isolate->debugger()->PrintBreakpointsToJSONArray(&jsarr); |
| 282 |
| 283 } else if (js->num_arguments() == 3) { |
| 284 // Print individual breakpoint. |
| 285 intptr_t id = atoi(js->GetArgument(2)); |
| 286 SourceBreakpoint* bpt = isolate->debugger()->GetBreakpointById(id); |
| 287 if (bpt != NULL) { |
| 288 bpt->PrintToJSONStream(js); |
| 289 } else { |
| 290 PrintError(js, "Unrecognized breakpoint id %s", js->GetArgument(2)); |
| 291 } |
| 292 |
| 293 } else { |
| 294 PrintError(js, "Command too long"); |
| 295 } |
| 296 } else { |
| 297 PrintError(js, "Unrecognized subcommand '%s'", js->GetArgument(1)); |
| 298 } |
| 299 } |
| 300 |
| 301 |
| 257 static ServiceMessageHandlerEntry __message_handlers[] = { | 302 static ServiceMessageHandlerEntry __message_handlers[] = { |
| 258 { "name", HandleName }, | 303 { "name", HandleName }, |
| 259 { "stacktrace", HandleStackTrace }, | 304 { "stacktrace", HandleStackTrace }, |
| 260 { "objecthistogram", HandleObjectHistogram}, | 305 { "objecthistogram", HandleObjectHistogram}, |
| 261 { "library", HandleLibrary }, | 306 { "library", HandleLibrary }, |
| 262 { "classes", HandleClasses }, | 307 { "classes", HandleClasses }, |
| 263 { "objects", HandleObjects }, | 308 { "objects", HandleObjects }, |
| 309 { "debug", HandleDebug }, |
| 264 { "_echo", HandleEcho }, | 310 { "_echo", HandleEcho }, |
| 265 }; | 311 }; |
| 266 | 312 |
| 267 | 313 |
| 268 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { | 314 static void HandleFallthrough(Isolate* isolate, JSONStream* js) { |
| 269 JSONObject jsobj(js); | 315 JSONObject jsobj(js); |
| 270 jsobj.AddProperty("type", "error"); | 316 jsobj.AddProperty("type", "Error"); |
| 271 jsobj.AddProperty("text", "request not understood."); | 317 jsobj.AddProperty("text", "request not understood."); |
| 272 PrintArgumentsAndOptions(jsobj, js); | 318 PrintArgumentsAndOptions(jsobj, js); |
| 273 } | 319 } |
| 274 | 320 |
| 275 | 321 |
| 276 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { | 322 static ServiceMessageHandler FindServiceMessageHandler(const char* command) { |
| 277 intptr_t num_message_handlers = sizeof(__message_handlers) / | 323 intptr_t num_message_handlers = sizeof(__message_handlers) / |
| 278 sizeof(__message_handlers[0]); | 324 sizeof(__message_handlers[0]); |
| 279 for (intptr_t i = 0; i < num_message_handlers; i++) { | 325 for (intptr_t i = 0; i < num_message_handlers; i++) { |
| 280 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; | 326 const ServiceMessageHandlerEntry& entry = __message_handlers[i]; |
| 281 if (!strcmp(command, entry.command)) { | 327 if (!strcmp(command, entry.command)) { |
| 282 return entry.handler; | 328 return entry.handler; |
| 283 } | 329 } |
| 284 } | 330 } |
| 285 return HandleFallthrough; | 331 return HandleFallthrough; |
| 286 } | 332 } |
| 287 | 333 |
| 288 } // namespace dart | 334 } // namespace dart |
| OLD | NEW |