Index: runtime/vm/service.cc |
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc |
index ace6b6ac3a4675c2b7105764aac18e88f0359fb5..cf52a439f1b05e72b9af0633f26ec180789c5cab 100644 |
--- a/runtime/vm/service.cc |
+++ b/runtime/vm/service.cc |
@@ -79,81 +79,23 @@ static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
return reinterpret_cast<uint8_t*>(new_ptr); |
} |
-static void PrintRequest(const JSONObject& obj, JSONStream* js) { |
- JSONObject jsobj(&obj, "request"); |
- jsobj.AddProperty("method", js->method()); |
- { |
- JSONObject params(&jsobj, "params"); |
- for (intptr_t i = 0; i < js->num_params(); i++) { |
- params.AddProperty(js->GetParamKey(i), js->GetParamValue(i)); |
- } |
- } |
-} |
- |
- |
-static void PrintError(JSONStream* js, |
- const char* format, ...) { |
- Isolate* isolate = Isolate::Current(); |
- |
- va_list args; |
- va_start(args, format); |
- intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
- va_end(args); |
- |
- char* buffer = isolate->current_zone()->Alloc<char>(len + 1); |
- va_list args2; |
- va_start(args2, format); |
- OS::VSNPrint(buffer, (len + 1), format, args2); |
- va_end(args2); |
- |
- JSONObject jsobj(js); |
- jsobj.AddProperty("type", "Error"); |
- jsobj.AddProperty("message", buffer); |
- PrintRequest(jsobj, js); |
-} |
- |
- |
static void PrintMissingParamError(JSONStream* js, |
const char* param) { |
- PrintError(js, "%s expects the '%s' parameter", |
- js->method(), param); |
+ js->PrintError(kInvalidParams, |
+ "%s expects the '%s' parameter", js->method(), param); |
} |
static void PrintInvalidParamError(JSONStream* js, |
const char* param) { |
- PrintError(js, "%s: invalid '%s' parameter: %s", |
- js->method(), param, js->LookupParam(param)); |
+ js->PrintError(kInvalidParams, |
+ "%s: invalid '%s' parameter: %s", |
+ js->method(), param, js->LookupParam(param)); |
} |
static void PrintUnrecognizedMethodError(JSONStream* js) { |
- PrintError(js, "unrecognized method: %s", js->method()); |
-} |
- |
- |
-static void PrintErrorWithKind(JSONStream* js, |
- const char* kind, |
- const char* format, ...) { |
- Isolate* isolate = Isolate::Current(); |
- |
- va_list args; |
- va_start(args, format); |
- intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
- va_end(args); |
- |
- char* buffer = isolate->current_zone()->Alloc<char>(len + 1); |
- va_list args2; |
- va_start(args2, format); |
- OS::VSNPrint(buffer, (len + 1), format, args2); |
- va_end(args2); |
- |
- JSONObject jsobj(js); |
- jsobj.AddProperty("type", "Error"); |
- jsobj.AddProperty("id", ""); |
- jsobj.AddProperty("kind", kind); |
- jsobj.AddProperty("message", buffer); |
- PrintRequest(jsobj, js); |
+ js->PrintError(kMethodNotFound, NULL); |
} |
@@ -1224,13 +1166,33 @@ static RawObject* LookupHeapObject(Isolate* isolate, |
} |
-static void PrintSentinel(JSONStream* js, |
- const char* id, |
- const char* preview) { |
+enum SentinelType { |
+ kCollectedSentinel, |
+ kExpiredSentinel, |
+ kFreeSentinel, |
+}; |
+ |
+ |
+static void PrintSentinel(JSONStream* js, SentinelType sentinel_type) { |
JSONObject jsobj(js); |
jsobj.AddProperty("type", "Sentinel"); |
- jsobj.AddProperty("id", id); |
- jsobj.AddProperty("valueAsString", preview); |
+ switch (sentinel_type) { |
+ case kCollectedSentinel: |
+ jsobj.AddProperty("kind", "Collected"); |
+ jsobj.AddProperty("valueAsString", "<collected>"); |
+ break; |
+ case kExpiredSentinel: |
+ jsobj.AddProperty("kind", "Expired"); |
+ jsobj.AddProperty("valueAsString", "<expired>"); |
+ break; |
+ case kFreeSentinel: |
+ jsobj.AddProperty("kind", "Free"); |
+ jsobj.AddProperty("valueAsString", "<free>"); |
+ break; |
+ default: |
+ UNIMPLEMENTED(); |
+ break; |
+ } |
} |
@@ -1268,9 +1230,10 @@ static bool PrintMessage(JSONStream* js, Isolate* isolate, const char* id) { |
isolate->message_handler()->AcquireQueues(&aq); |
Message* message = aq.queue()->FindMessageById(message_id); |
if (message == NULL) { |
- printf("Could not find message %" Px "\n", message_id); |
- // Not found. |
- return false; |
+ // The user may try to load an expired message, so we treat |
+ // unrecognized ids as if they are expired. |
+ PrintSentinel(js, kExpiredSentinel); |
+ return true; |
} |
SnapshotReader reader(message->data(), |
message->len(), |
@@ -1280,8 +1243,6 @@ static bool PrintMessage(JSONStream* js, Isolate* isolate, const char* id) { |
const Object& msg_obj = Object::Handle(reader.ReadObject()); |
msg_obj.PrintJSON(js); |
return true; |
- } else { |
- printf("Could not get id from %s\n", rest); |
} |
} |
return false; |
@@ -1349,7 +1310,7 @@ static bool GetInboundReferences(Isolate* isolate, JSONStream* js) { |
return true; |
} |
const char* limit_cstr = js->LookupParam("limit"); |
- if (target_id == NULL) { |
+ if (limit_cstr == NULL) { |
PrintMissingParamError(js, "limit"); |
return true; |
} |
@@ -1367,17 +1328,12 @@ static bool GetInboundReferences(Isolate* isolate, JSONStream* js) { |
} |
if (obj.raw() == Object::sentinel().raw()) { |
if (lookup_result == ObjectIdRing::kCollected) { |
- PrintErrorWithKind( |
- js, "InboundReferencesCollected", |
- "attempt to find a retaining path for a collected object\n"); |
- return true; |
+ PrintSentinel(js, kCollectedSentinel); |
} else if (lookup_result == ObjectIdRing::kExpired) { |
- PrintErrorWithKind( |
- js, "InboundReferencesExpired", |
- "attempt to find a retaining path for an expired object\n"); |
- return true; |
+ PrintSentinel(js, kExpiredSentinel); |
+ } else { |
+ PrintInvalidParamError(js, "targetId"); |
} |
- PrintInvalidParamError(js, "targetId"); |
return true; |
} |
return PrintInboundReferences(isolate, &obj, limit, js); |
@@ -1453,7 +1409,7 @@ static bool GetRetainingPath(Isolate* isolate, JSONStream* js) { |
return true; |
} |
const char* limit_cstr = js->LookupParam("limit"); |
- if (target_id == NULL) { |
+ if (limit_cstr == NULL) { |
PrintMissingParamError(js, "limit"); |
return true; |
} |
@@ -1471,17 +1427,12 @@ static bool GetRetainingPath(Isolate* isolate, JSONStream* js) { |
} |
if (obj.raw() == Object::sentinel().raw()) { |
if (lookup_result == ObjectIdRing::kCollected) { |
- PrintErrorWithKind( |
- js, "RetainingPathCollected", |
- "attempt to find a retaining path for a collected object\n"); |
- return true; |
+ PrintSentinel(js, kCollectedSentinel); |
} else if (lookup_result == ObjectIdRing::kExpired) { |
- PrintErrorWithKind( |
- js, "RetainingPathExpired", |
- "attempt to find a retaining path for an expired object\n"); |
- return true; |
+ PrintSentinel(js, kExpiredSentinel); |
+ } else { |
+ PrintInvalidParamError(js, "targetId"); |
} |
- PrintInvalidParamError(js, "targetId"); |
return true; |
} |
return PrintRetainingPath(isolate, &obj, limit, js); |
@@ -1505,17 +1456,12 @@ static bool GetRetainedSize(Isolate* isolate, JSONStream* js) { |
&lookup_result)); |
if (obj.raw() == Object::sentinel().raw()) { |
if (lookup_result == ObjectIdRing::kCollected) { |
- PrintErrorWithKind( |
- js, "RetainedCollected", |
- "attempt to calculate size retained by a collected object\n"); |
- return true; |
+ PrintSentinel(js, kCollectedSentinel); |
} else if (lookup_result == ObjectIdRing::kExpired) { |
- PrintErrorWithKind( |
- js, "RetainedExpired", |
- "attempt to calculate size retained by an expired object\n"); |
- return true; |
+ PrintSentinel(js, kExpiredSentinel); |
+ } else { |
+ PrintInvalidParamError(js, "targetId"); |
} |
- PrintInvalidParamError(js, "targetId"); |
return true; |
} |
if (obj.IsClass()) { |
@@ -1534,9 +1480,10 @@ static bool GetRetainedSize(Isolate* isolate, JSONStream* js) { |
result.PrintJSON(js, true); |
return true; |
} |
- PrintError(js, "%s: Invalid 'targetId' parameter value: " |
- "id '%s' does not correspond to a " |
- "library, class, or instance", js->method(), target_id); |
+ js->PrintError(kInvalidParams, |
+ "%s: invalid 'targetId' parameter: " |
+ "id '%s' does not correspond to a " |
+ "library, class, or instance", js->method(), target_id); |
return true; |
} |
@@ -1564,9 +1511,9 @@ static bool Eval(Isolate* isolate, JSONStream* js) { |
&lookup_result)); |
if (obj.raw() == Object::sentinel().raw()) { |
if (lookup_result == ObjectIdRing::kCollected) { |
- PrintSentinel(js, "objects/collected", "<collected>"); |
+ PrintSentinel(js, kCollectedSentinel); |
} else if (lookup_result == ObjectIdRing::kExpired) { |
- PrintSentinel(js, "objects/expired", "<expired>"); |
+ PrintSentinel(js, kExpiredSentinel); |
} else { |
PrintInvalidParamError(js, "targetId"); |
} |
@@ -1600,9 +1547,10 @@ static bool Eval(Isolate* isolate, JSONStream* js) { |
result.PrintJSON(js, true); |
return true; |
} |
- PrintError(js, "%s: Invalid 'targetId' parameter value: " |
- "id '%s' does not correspond to a " |
- "library, class, or instance", js->method(), target_id); |
+ js->PrintError(kInvalidParams, |
+ "%s: invalid 'targetId' parameter: " |
+ "id '%s' does not correspond to a " |
+ "library, class, or instance", js->method(), target_id); |
return true; |
} |
@@ -1678,7 +1626,7 @@ static bool GetInstances(Isolate* isolate, JSONStream* js) { |
return true; |
} |
const char* limit_cstr = js->LookupParam("limit"); |
- if (target_id == NULL) { |
+ if (limit_cstr == NULL) { |
PrintMissingParamError(js, "limit"); |
return true; |
} |
@@ -1809,9 +1757,11 @@ static bool GetHitsOrSites(Isolate* isolate, JSONStream* js, bool as_sites) { |
CodeCoverage::PrintJSON(isolate, js, &ff, as_sites); |
return true; |
} |
- PrintError(js, "%s: Invalid 'targetId' parameter value: " |
- "id '%s' does not correspond to a " |
- "script, library, class, or function", js->method(), target_id); |
+ js->PrintError(kInvalidParams, |
+ "%s: invalid 'targetId' parameter: " |
+ "id '%s' does not correspond to a " |
+ "script, library, class, or function", |
+ js->method(), target_id); |
return true; |
} |
@@ -1862,7 +1812,7 @@ static bool AddBreakpoint(Isolate* isolate, JSONStream* js) { |
SourceBreakpoint* bpt = |
isolate->debugger()->SetBreakpointAtLine(script_url, line); |
if (bpt == NULL) { |
- PrintError(js, "Unable to set breakpoint at line %s", line_param); |
+ js->PrintError(kNoBreakAtLine, NULL); |
return true; |
} |
bpt->PrintJSON(js); |
@@ -1888,9 +1838,7 @@ static bool AddBreakpointAtEntry(Isolate* isolate, JSONStream* js) { |
SourceBreakpoint* bpt = |
isolate->debugger()->SetBreakpointAtEntry(function); |
if (bpt == NULL) { |
- const String& funcName = String::Handle(function.PrettyName()); |
- PrintError(js, "Unable to set breakpoint at function '%s'", |
- funcName.ToCString()); |
+ js->PrintError(kNoBreakAtFunction, NULL); |
return true; |
} |
bpt->PrintJSON(js); |
@@ -1968,7 +1916,7 @@ static bool HandleNativeMetric(Isolate* isolate, |
} |
current = current->next(); |
} |
- PrintError(js, "Native Metric %s not found\n", id); |
+ PrintInvalidParamError(js, "metricId"); |
return true; |
} |
@@ -2015,7 +1963,7 @@ static bool HandleDartMetric(Isolate* isolate, JSONStream* js, const char* id) { |
buffer->AddString(String::Cast(result).ToCString()); |
return true; |
} |
- PrintError(js, "Dart Metric %s not found\n", id); |
+ PrintInvalidParamError(js, "metricId"); |
return true; |
} |
@@ -2064,7 +2012,8 @@ static bool GetIsolateMetric(Isolate* isolate, JSONStream* js) { |
static const char* kMetricIdPrefix = "metrics/"; |
static intptr_t kMetricIdPrefixLen = strlen(kMetricIdPrefix); |
if (strncmp(metric_id, kMetricIdPrefix, kMetricIdPrefixLen) != 0) { |
- PrintError(js, "Metric %s not found\n", metric_id); |
+ PrintInvalidParamError(js, "metricId"); |
+ return true; |
} |
// Check if id begins with "metrics/native/". |
static const char* kNativeMetricIdPrefix = "metrics/native/"; |
@@ -2150,7 +2099,7 @@ static bool Resume(Isolate* isolate, JSONStream* js) { |
return true; |
} |
- PrintError(js, "VM was not paused"); |
+ js->PrintError(kVMMustBePaused, NULL); |
return true; |
} |
@@ -2376,7 +2325,7 @@ static bool GetObjectByAddress(Isolate* isolate, JSONStream* js) { |
object = isolate->heap()->FindObject(&visitor); |
} |
if (object.IsNull()) { |
- PrintSentinel(js, "objects/free", "<free>"); |
+ PrintSentinel(js, kFreeSentinel); |
} else { |
object.PrintJSON(js, ref); |
} |
@@ -2428,10 +2377,10 @@ static bool GetObject(Isolate* isolate, JSONStream* js) { |
obj.PrintJSON(js, false); |
return true; |
} else if (lookup_result == ObjectIdRing::kCollected) { |
- PrintSentinel(js, "objects/collected", "<collected>"); |
+ PrintSentinel(js, kCollectedSentinel); |
return true; |
} else if (lookup_result == ObjectIdRing::kExpired) { |
- PrintSentinel(js, "objects/expired", "<expired>"); |
+ PrintSentinel(js, kExpiredSentinel); |
return true; |
} |
@@ -2446,7 +2395,7 @@ static bool GetObject(Isolate* isolate, JSONStream* js) { |
return true; |
} |
- PrintError(js, "Unrecognized object id: %s\n", id); |
+ PrintInvalidParamError(js, "objectId"); |
return true; |
} |