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