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 "include/dart_debugger_api.h" | 5 #include "include/dart_debugger_api.h" |
6 #include "vm/dart_api_impl.h" | 6 #include "vm/dart_api_impl.h" |
7 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
8 #include "vm/debugger.h" | 8 #include "vm/debugger.h" |
9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
10 #include "vm/message_handler.h" | 10 #include "vm/message_handler.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 | 47 |
48 static RawInstance* Eval(Dart_Handle lib, const char* expr) { | 48 static RawInstance* Eval(Dart_Handle lib, const char* expr) { |
49 Dart_Handle result = Dart_EvaluateExpr(lib, NewString(expr)); | 49 Dart_Handle result = Dart_EvaluateExpr(lib, NewString(expr)); |
50 EXPECT_VALID(result); | 50 EXPECT_VALID(result); |
51 Isolate* isolate = Isolate::Current(); | 51 Isolate* isolate = Isolate::Current(); |
52 const Instance& instance = Api::UnwrapInstanceHandle(isolate, result); | 52 const Instance& instance = Api::UnwrapInstanceHandle(isolate, result); |
53 return instance.raw(); | 53 return instance.raw(); |
54 } | 54 } |
55 | 55 |
56 | 56 |
| 57 static RawInstance* EvalF(Dart_Handle lib, const char* fmt, ...) { |
| 58 Isolate* isolate = Isolate::Current(); |
| 59 |
| 60 va_list args; |
| 61 va_start(args, fmt); |
| 62 intptr_t len = OS::VSNPrint(NULL, 0, fmt, args); |
| 63 va_end(args); |
| 64 |
| 65 char* buffer = isolate->current_zone()->Alloc<char>(len + 1); |
| 66 va_list args2; |
| 67 va_start(args2, fmt); |
| 68 OS::VSNPrint(buffer, (len + 1), fmt, args2); |
| 69 va_end(args2); |
| 70 |
| 71 return Eval(lib, buffer); |
| 72 } |
| 73 |
| 74 |
| 75 static RawFunction* GetFunction(const Class& cls, const char* name) { |
| 76 const Function& result = Function::Handle(cls.LookupDynamicFunction( |
| 77 String::Handle(String::New(name)))); |
| 78 EXPECT(!result.IsNull()); |
| 79 return result.raw(); |
| 80 } |
| 81 |
| 82 |
| 83 static RawClass* GetClass(const Library& lib, const char* name) { |
| 84 const Class& cls = Class::Handle( |
| 85 lib.LookupClass(String::Handle(Symbols::New(name)))); |
| 86 EXPECT(!cls.IsNull()); // No ambiguity error expected. |
| 87 return cls.raw(); |
| 88 } |
| 89 |
| 90 |
57 TEST_CASE(Service_DebugBreakpoints) { | 91 TEST_CASE(Service_DebugBreakpoints) { |
58 const char* kScript = | 92 const char* kScript = |
59 "var port;\n" // Set to our mock port by C++. | 93 "var port;\n" // Set to our mock port by C++. |
60 "\n" | 94 "\n" |
61 "main() {\n" // We set breakpoint here. | 95 "main() {\n" // We set breakpoint here. |
62 "}"; | 96 "}"; |
63 | 97 |
64 Isolate* isolate = Isolate::Current(); | 98 Isolate* isolate = Isolate::Current(); |
65 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); | 99 Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); |
66 EXPECT_VALID(lib); | 100 EXPECT_VALID(lib); |
(...skipping 13 matching lines...) Expand all Loading... |
80 isolate->debugger()->SetBreakpointAtLine(url, 3); | 114 isolate->debugger()->SetBreakpointAtLine(url, 3); |
81 | 115 |
82 // Get the breakpoint list. | 116 // Get the breakpoint list. |
83 service_msg = Eval(lib, "[port, ['debug', 'breakpoints'], [], []]"); | 117 service_msg = Eval(lib, "[port, ['debug', 'breakpoints'], [], []]"); |
84 Service::HandleServiceMessage(isolate, service_msg); | 118 Service::HandleServiceMessage(isolate, service_msg); |
85 handler.HandleNextMessage(); | 119 handler.HandleNextMessage(); |
86 EXPECT_STREQ( | 120 EXPECT_STREQ( |
87 "{\"type\":\"BreakpointList\",\"breakpoints\":[{" | 121 "{\"type\":\"BreakpointList\",\"breakpoints\":[{" |
88 "\"type\":\"Breakpoint\",\"id\":1,\"enabled\":true," | 122 "\"type\":\"Breakpoint\",\"id\":1,\"enabled\":true," |
89 "\"resolved\":false," | 123 "\"resolved\":false," |
90 "\"location\":{\"type\":\"Location\",\"libId\":12," | 124 "\"location\":{\"type\":\"Location\"," |
91 "\"script\":\"dart:test-lib\",\"tokenPos\":5}}]}", | 125 "\"script\":\"dart:test-lib\",\"tokenPos\":5}}]}", |
92 handler.msg()); | 126 handler.msg()); |
93 | 127 |
94 // Individual breakpoint. | 128 // Individual breakpoint. |
95 service_msg = Eval(lib, "[port, ['debug', 'breakpoints', '1'], [], []]"); | 129 service_msg = Eval(lib, "[port, ['debug', 'breakpoints', '1'], [], []]"); |
96 Service::HandleServiceMessage(isolate, service_msg); | 130 Service::HandleServiceMessage(isolate, service_msg); |
97 handler.HandleNextMessage(); | 131 handler.HandleNextMessage(); |
98 EXPECT_STREQ( | 132 EXPECT_STREQ( |
99 "{\"type\":\"Breakpoint\",\"id\":1,\"enabled\":true," | 133 "{\"type\":\"Breakpoint\",\"id\":1,\"enabled\":true," |
100 "\"resolved\":false," | 134 "\"resolved\":false," |
101 "\"location\":{\"type\":\"Location\",\"libId\":12," | 135 "\"location\":{\"type\":\"Location\"," |
102 "\"script\":\"dart:test-lib\",\"tokenPos\":5}}", | 136 "\"script\":\"dart:test-lib\",\"tokenPos\":5}}", |
103 handler.msg()); | 137 handler.msg()); |
104 | 138 |
105 // Missing sub-command. | 139 // Missing sub-command. |
106 service_msg = Eval(lib, "[port, ['debug'], [], []]"); | 140 service_msg = Eval(lib, "[port, ['debug'], [], []]"); |
107 Service::HandleServiceMessage(isolate, service_msg); | 141 Service::HandleServiceMessage(isolate, service_msg); |
108 handler.HandleNextMessage(); | 142 handler.HandleNextMessage(); |
109 EXPECT_STREQ( | 143 EXPECT_STREQ( |
110 "{\"type\":\"Error\"," | 144 "{\"type\":\"Error\"," |
111 "\"text\":\"Must specify a subcommand\"," | 145 "\"text\":\"Must specify a subcommand\"," |
(...skipping 27 matching lines...) Expand all Loading... |
139 service_msg = Eval(lib, "[port, ['debug', 'nosferatu'], [], []]"); | 173 service_msg = Eval(lib, "[port, ['debug', 'nosferatu'], [], []]"); |
140 Service::HandleServiceMessage(isolate, service_msg); | 174 Service::HandleServiceMessage(isolate, service_msg); |
141 handler.HandleNextMessage(); | 175 handler.HandleNextMessage(); |
142 EXPECT_STREQ("{\"type\":\"Error\"," | 176 EXPECT_STREQ("{\"type\":\"Error\"," |
143 "\"text\":\"Unrecognized subcommand 'nosferatu'\"," | 177 "\"text\":\"Unrecognized subcommand 'nosferatu'\"," |
144 "\"message\":{\"arguments\":[\"debug\",\"nosferatu\"]," | 178 "\"message\":{\"arguments\":[\"debug\",\"nosferatu\"]," |
145 "\"option_keys\":[],\"option_values\":[]}}", | 179 "\"option_keys\":[],\"option_values\":[]}}", |
146 handler.msg()); | 180 handler.msg()); |
147 } | 181 } |
148 | 182 |
| 183 |
| 184 TEST_CASE(Service_Classes) { |
| 185 const char* kScript = |
| 186 "var port;\n" // Set to our mock port by C++. |
| 187 "\n" |
| 188 "class A {\n" |
| 189 " var a;\n" |
| 190 " dynamic b() {}\n" |
| 191 " dynamic c() {\n" |
| 192 " var d = () { b(); };\n" |
| 193 " return d;\n" |
| 194 " }\n" |
| 195 "}\n" |
| 196 "main() {\n" |
| 197 " var z = new A();\n" |
| 198 " var x = z.c();\n" |
| 199 " x();\n" |
| 200 "}"; |
| 201 |
| 202 Isolate* isolate = Isolate::Current(); |
| 203 Dart_Handle h_lib = TestCase::LoadTestScript(kScript, NULL); |
| 204 EXPECT_VALID(h_lib); |
| 205 Library& lib = Library::Handle(); |
| 206 lib ^= Api::UnwrapHandle(h_lib); |
| 207 EXPECT(!lib.IsNull()); |
| 208 Dart_Handle result = Dart_Invoke(h_lib, NewString("main"), 0, NULL); |
| 209 EXPECT_VALID(result); |
| 210 const Class& class_a = Class::Handle(GetClass(lib, "A")); |
| 211 EXPECT(!class_a.IsNull()); |
| 212 intptr_t cid = class_a.id(); |
| 213 |
| 214 // Build a mock message handler and wrap it in a dart port. |
| 215 ServiceTestMessageHandler handler; |
| 216 Dart_Port port_id = PortMap::CreatePort(&handler); |
| 217 Dart_Handle port = |
| 218 Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id)); |
| 219 EXPECT_VALID(port); |
| 220 EXPECT_VALID(Dart_SetField(h_lib, NewString("port"), port)); |
| 221 |
| 222 Instance& service_msg = Instance::Handle(); |
| 223 |
| 224 // Request an invalid class id. |
| 225 service_msg = Eval(h_lib, "[port, ['classes', '999999'], [], []]"); |
| 226 Service::HandleServiceMessage(isolate, service_msg); |
| 227 handler.HandleNextMessage(); |
| 228 EXPECT_STREQ( |
| 229 "{\"type\":\"Error\",\"text\":\"999999 is not a valid class id.\"," |
| 230 "\"message\":{\"arguments\":[\"classes\",\"999999\"]," |
| 231 "\"option_keys\":[],\"option_values\":[]}}", handler.msg()); |
| 232 |
| 233 // Request the class A over the service. |
| 234 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "'], [], []]", cid); |
| 235 Service::HandleServiceMessage(isolate, service_msg); |
| 236 handler.HandleNextMessage(); |
| 237 EXPECT_STREQ( |
| 238 "{\"type\":\"Class\",\"id\":\"classes\\/1009\",\"name\":\"A\"," |
| 239 "\"user_name\":\"A\",\"implemented\":false,\"abstract\":false," |
| 240 "\"patch\":false,\"finalized\":true,\"const\":false,\"super\":" |
| 241 "{\"type\":\"@Class\",\"id\":\"classes\\/35\",\"name\":\"Object\"," |
| 242 "\"user_name\":\"Object\"},\"library\":{\"type\":\"@Library\",\"id\":" |
| 243 "\"libraries\\/12\",\"name\":\"\",\"user_name\":\"dart:test-lib\"}," |
| 244 "\"fields\":[{\"type\":\"@Field\",\"id\":\"classes\\/1009\\/fields\\/0\"," |
| 245 "\"name\":\"a\",\"user_name\":\"a\",\"owner\":{\"type\":\"@Class\"," |
| 246 "\"id\":\"classes\\/1009\",\"name\":\"A\",\"user_name\":\"A\"}," |
| 247 "\"declared_type\":{\"type\":\"@Class\",\"id\":\"classes\\/106\"," |
| 248 "\"name\":\"dynamic\",\"user_name\":\"dynamic\"},\"static\":false," |
| 249 "\"final\":false,\"const\":false}],\"functions\":[" |
| 250 "{\"type\":\"@Function\",\"id\":\"classes\\/1009\\/functions\\/0\"," |
| 251 "\"name\":\"get:a\",\"user_name\":\"A.a\"},{\"type\":\"@Function\"," |
| 252 "\"id\":\"classes\\/1009\\/functions\\/1\",\"name\":\"set:a\"," |
| 253 "\"user_name\":\"A.a=\"},{\"type\":\"@Function\",\"id\":" |
| 254 "\"classes\\/1009\\/functions\\/2\",\"name\":\"b\",\"user_name\":\"A.b\"}" |
| 255 ",{\"type\":\"@Function\",\"id\":\"classes\\/1009\\/functions\\/3\"," |
| 256 "\"name\":\"c\",\"user_name\":\"A.c\"},{\"type\":\"@Function\",\"id\":" |
| 257 "\"classes\\/1009\\/functions\\/4\",\"name\":\"A.\",\"user_name\":" |
| 258 "\"A.A\"}]}", |
| 259 handler.msg()); |
| 260 |
| 261 // Request function 0 from class A. |
| 262 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '0']," |
| 263 "[], []]", cid); |
| 264 Service::HandleServiceMessage(isolate, service_msg); |
| 265 handler.HandleNextMessage(); |
| 266 EXPECT_STREQ( |
| 267 "{\"type\":\"Function\",\"id\":\"classes\\/1009\\/functions\\/0\",\"name\":" |
| 268 "\"get:a\",\"user_name\":\"A.a\",\"is_static\":false,\"is_const\":false," |
| 269 "\"is_optimizable\":true,\"is_inlinable\":false,\"kind\":" |
| 270 "\"kImplicitGetter\",\"unoptimized_code\":{\"type\":\"null\"}," |
| 271 "\"usage_counter\":0,\"optimized_call_site_count\":0,\"code\":" |
| 272 "{\"type\":\"null\"},\"deoptimizations\":0}", handler.msg()); |
| 273 |
| 274 // Request field 0 from class A. |
| 275 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '0']," |
| 276 "[], []]", cid); |
| 277 Service::HandleServiceMessage(isolate, service_msg); |
| 278 handler.HandleNextMessage(); |
| 279 EXPECT_STREQ( |
| 280 "{\"type\":\"Field\",\"id\":\"classes\\/1009\\/fields\\/0\",\"name\":\"a\"," |
| 281 "\"user_name\":\"a\",\"owner\":{\"type\":\"@Class\",\"id\":" |
| 282 "\"classes\\/1009\",\"name\":\"A\",\"user_name\":\"A\"},\"declared_type\":" |
| 283 "{\"type\":\"@Class\",\"id\":\"classes\\/106\",\"name\":\"dynamic\"," |
| 284 "\"user_name\":\"dynamic\"},\"static\":false,\"final\":false,\"const\":" |
| 285 "false,\"guard_nullable\":true,\"guard_class\":{\"type\":\"@Class\"," |
| 286 "\"id\":\"classes\\/105\",\"name\":\"Null\",\"user_name\":\"Null\"}," |
| 287 "\"guard_length\":\"variable\"}", handler.msg()); |
| 288 |
| 289 // Invalid sub command. |
| 290 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'huh', '0']," |
| 291 "[], []]", cid); |
| 292 Service::HandleServiceMessage(isolate, service_msg); |
| 293 handler.HandleNextMessage(); |
| 294 EXPECT_STREQ( |
| 295 "{\"type\":\"Error\",\"text\":\"Invalid sub collection huh\",\"message\":" |
| 296 "{\"arguments\":[\"classes\",\"1009\",\"huh\",\"0\"],\"option_keys\":[]," |
| 297 "\"option_values\":[]}}", handler.msg()); |
| 298 |
| 299 // Invalid field request. |
| 300 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '9']," |
| 301 "[], []]", cid); |
| 302 Service::HandleServiceMessage(isolate, service_msg); |
| 303 handler.HandleNextMessage(); |
| 304 EXPECT_STREQ( |
| 305 "{\"type\":\"Error\",\"text\":\"Field 9 not found\"," |
| 306 "\"message\":{\"arguments\":[\"classes\",\"1009\",\"fields\",\"9\"]," |
| 307 "\"option_keys\":[],\"option_values\":[]}}", handler.msg()); |
| 308 |
| 309 // Invalid function request. |
| 310 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '9']," |
| 311 "[], []]", cid); |
| 312 Service::HandleServiceMessage(isolate, service_msg); |
| 313 handler.HandleNextMessage(); |
| 314 EXPECT_STREQ( |
| 315 "{\"type\":\"Error\",\"text\":\"Function 9 not found\"," |
| 316 "\"message\":{\"arguments\":[\"classes\",\"1009\",\"functions\",\"9\"]," |
| 317 "\"option_keys\":[],\"option_values\":[]}}", handler.msg()); |
| 318 |
| 319 |
| 320 // Invalid field subcommand. |
| 321 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'fields', '9', 'x']" |
| 322 ",[], []]", cid); |
| 323 Service::HandleServiceMessage(isolate, service_msg); |
| 324 handler.HandleNextMessage(); |
| 325 EXPECT_STREQ( |
| 326 "{\"type\":\"Error\",\"text\":\"Command too long\",\"message\":" |
| 327 "{\"arguments\":[\"classes\",\"1009\",\"fields\",\"9\",\"x\"]," |
| 328 "\"option_keys\":[],\"option_values\":[]}}", |
| 329 handler.msg()); |
| 330 |
| 331 // Invalid function request. |
| 332 service_msg = EvalF(h_lib, "[port, ['classes', '%" Pd "', 'functions', '9'," |
| 333 "'x'], [], []]", cid); |
| 334 Service::HandleServiceMessage(isolate, service_msg); |
| 335 handler.HandleNextMessage(); |
| 336 EXPECT_STREQ( |
| 337 "{\"type\":\"Error\",\"text\":\"Command too long\",\"message\":" |
| 338 "{\"arguments\":[\"classes\",\"1009\",\"functions\",\"9\",\"x\"]," |
| 339 "\"option_keys\":[],\"option_values\":[]}}", |
| 340 handler.msg()); |
| 341 } |
| 342 |
| 343 |
| 344 TEST_CASE(Service_Code) { |
| 345 const char* kScript = |
| 346 "var port;\n" // Set to our mock port by C++. |
| 347 "\n" |
| 348 "class A {\n" |
| 349 " var a;\n" |
| 350 " dynamic b() {}\n" |
| 351 " dynamic c() {\n" |
| 352 " var d = () { b(); };\n" |
| 353 " return d;\n" |
| 354 " }\n" |
| 355 "}\n" |
| 356 "main() {\n" |
| 357 " var z = new A();\n" |
| 358 " var x = z.c();\n" |
| 359 " x();\n" |
| 360 "}"; |
| 361 |
| 362 Isolate* isolate = Isolate::Current(); |
| 363 Dart_Handle h_lib = TestCase::LoadTestScript(kScript, NULL); |
| 364 EXPECT_VALID(h_lib); |
| 365 Library& lib = Library::Handle(); |
| 366 lib ^= Api::UnwrapHandle(h_lib); |
| 367 EXPECT(!lib.IsNull()); |
| 368 Dart_Handle result = Dart_Invoke(h_lib, NewString("main"), 0, NULL); |
| 369 EXPECT_VALID(result); |
| 370 const Class& class_a = Class::Handle(GetClass(lib, "A")); |
| 371 EXPECT(!class_a.IsNull()); |
| 372 const Function& function_c = Function::Handle(GetFunction(class_a, "c")); |
| 373 EXPECT(!function_c.IsNull()); |
| 374 const Code& code_c = Code::Handle(function_c.CurrentCode()); |
| 375 EXPECT(!code_c.IsNull()); |
| 376 // Use the entry of the code object as it's reference. |
| 377 uword entry = code_c.EntryPoint(); |
| 378 EXPECT_GT(code_c.Size(), 16); |
| 379 uword last = entry + code_c.Size(); |
| 380 |
| 381 // Build a mock message handler and wrap it in a dart port. |
| 382 ServiceTestMessageHandler handler; |
| 383 Dart_Port port_id = PortMap::CreatePort(&handler); |
| 384 Dart_Handle port = |
| 385 Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id)); |
| 386 EXPECT_VALID(port); |
| 387 EXPECT_VALID(Dart_SetField(h_lib, NewString("port"), port)); |
| 388 |
| 389 Instance& service_msg = Instance::Handle(); |
| 390 |
| 391 // Request an invalid code object. |
| 392 service_msg = Eval(h_lib, "[port, ['code', '0'], [], []]"); |
| 393 Service::HandleServiceMessage(isolate, service_msg); |
| 394 handler.HandleNextMessage(); |
| 395 EXPECT_STREQ( |
| 396 "{\"type\":\"Error\",\"text\":\"Could not find code at 0\",\"message\":" |
| 397 "{\"arguments\":[\"code\",\"0\"]," |
| 398 "\"option_keys\":[],\"option_values\":[]}}", handler.msg()); |
| 399 |
| 400 // The following four tests check that a code object can be found |
| 401 // inside the range: [code.EntryPoint(), code.EntryPoint() + code.Size()). |
| 402 // Request code object at code.EntryPoint() |
| 403 // Expect this to succeed as it is inside [entry, entry + size). |
| 404 service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", entry); |
| 405 Service::HandleServiceMessage(isolate, service_msg); |
| 406 handler.HandleNextMessage(); |
| 407 { |
| 408 // Only perform a partial match. |
| 409 const intptr_t kBufferSize = 512; |
| 410 char buffer[kBufferSize]; |
| 411 OS::SNPrint(buffer, kBufferSize-1, |
| 412 "{\"type\":\"Code\",\"id\":\"code\\/%" Px "\",", entry); |
| 413 EXPECT_SUBSTRING(buffer, handler.msg()); |
| 414 } |
| 415 |
| 416 // Request code object at code.EntryPoint() + 16. |
| 417 // Expect this to succeed as it is inside [entry, entry + size). |
| 418 uintptr_t address = entry + 16; |
| 419 service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", address); |
| 420 Service::HandleServiceMessage(isolate, service_msg); |
| 421 handler.HandleNextMessage(); |
| 422 { |
| 423 // Only perform a partial match. |
| 424 const intptr_t kBufferSize = 512; |
| 425 char buffer[kBufferSize]; |
| 426 OS::SNPrint(buffer, kBufferSize-1, |
| 427 "{\"type\":\"Code\",\"id\":\"code\\/%" Px "\",", entry); |
| 428 EXPECT_SUBSTRING(buffer, handler.msg()); |
| 429 } |
| 430 |
| 431 // Request code object at code.EntryPoint() + code.Size() - 1. |
| 432 // Expect this to succeed as it is inside [entry, entry + size). |
| 433 address = last - 1; |
| 434 service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", address); |
| 435 Service::HandleServiceMessage(isolate, service_msg); |
| 436 handler.HandleNextMessage(); |
| 437 { |
| 438 // Only perform a partial match. |
| 439 const intptr_t kBufferSize = 512; |
| 440 char buffer[kBufferSize]; |
| 441 OS::SNPrint(buffer, kBufferSize-1, |
| 442 "{\"type\":\"Code\",\"id\":\"code\\/%" Px "\",", entry); |
| 443 EXPECT_SUBSTRING(buffer, handler.msg()); |
| 444 } |
| 445 |
| 446 // Request code object at code.EntryPoint() + code.Size(). Expect this |
| 447 // to fail as it's outside of [entry, entry + size). |
| 448 address = last; |
| 449 service_msg = EvalF(h_lib, "[port, ['code', '%" Px "'], [], []]", address); |
| 450 Service::HandleServiceMessage(isolate, service_msg); |
| 451 handler.HandleNextMessage(); |
| 452 { |
| 453 const intptr_t kBufferSize = 1024; |
| 454 char buffer[kBufferSize]; |
| 455 OS::SNPrint(buffer, kBufferSize-1, |
| 456 "{\"type\":\"Error\",\"text\":\"Could not find code at %" Px "\"," |
| 457 "\"message\":{\"arguments\":[\"code\",\"%" Px "\"]," |
| 458 "\"option_keys\":[],\"option_values\":[]}}", address, address); |
| 459 EXPECT_STREQ(buffer, handler.msg()); |
| 460 } |
| 461 } |
| 462 |
149 } // namespace dart | 463 } // namespace dart |
OLD | NEW |