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 |