| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 | 6 |
| 7 #include "vm/code_index_table.h" | 7 #include "vm/code_index_table.h" |
| 8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 11 #include "vm/flags.h" |
| 11 #include "vm/globals.h" | 12 #include "vm/globals.h" |
| 13 #include "vm/longjump.h" |
| 12 #include "vm/object.h" | 14 #include "vm/object.h" |
| 13 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
| 14 #include "vm/os.h" | 16 #include "vm/os.h" |
| 15 #include "vm/stack_frame.h" | 17 #include "vm/stack_frame.h" |
| 16 #include "vm/stub_code.h" | 18 #include "vm/stub_code.h" |
| 17 #include "vm/visitor.h" | 19 #include "vm/visitor.h" |
| 18 | 20 |
| 19 | 21 |
| 20 namespace dart { | 22 namespace dart { |
| 21 | 23 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 return chars; | 220 return chars; |
| 219 } | 221 } |
| 220 | 222 |
| 221 | 223 |
| 222 void StackTrace::AddActivation(ActivationFrame* frame) { | 224 void StackTrace::AddActivation(ActivationFrame* frame) { |
| 223 this->trace_.Add(frame); | 225 this->trace_.Add(frame); |
| 224 } | 226 } |
| 225 | 227 |
| 226 | 228 |
| 227 Debugger::Debugger() | 229 Debugger::Debugger() |
| 228 : initialized_(false), | 230 : isolate_(NULL), |
| 231 initialized_(false), |
| 229 bp_handler_(NULL), | 232 bp_handler_(NULL), |
| 230 breakpoints_(NULL) { | 233 breakpoints_(NULL) { |
| 231 } | 234 } |
| 232 | 235 |
| 233 | 236 |
| 234 Debugger::~Debugger() { | 237 Debugger::~Debugger() { |
| 235 ASSERT(breakpoints_ == NULL); | 238 ASSERT(breakpoints_ == NULL); |
| 236 } | 239 } |
| 237 | 240 |
| 238 | 241 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function) { | 376 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function) { |
| 374 ASSERT(!target_function.IsNull()); | 377 ASSERT(!target_function.IsNull()); |
| 375 return SetBreakpoint(target_function, target_function.token_index()); | 378 return SetBreakpoint(target_function, target_function.token_index()); |
| 376 } | 379 } |
| 377 | 380 |
| 378 | 381 |
| 379 Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url, | 382 Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url, |
| 380 intptr_t line_number) { | 383 intptr_t line_number) { |
| 381 Library& lib = Library::Handle(); | 384 Library& lib = Library::Handle(); |
| 382 Script& script = Script::Handle(); | 385 Script& script = Script::Handle(); |
| 383 Isolate* isolate = Isolate::Current(); | 386 lib = isolate_->object_store()->registered_libraries(); |
| 384 ASSERT(isolate != NULL); | |
| 385 lib = isolate->object_store()->registered_libraries(); | |
| 386 while (!lib.IsNull()) { | 387 while (!lib.IsNull()) { |
| 387 script = lib.LookupScript(script_url); | 388 script = lib.LookupScript(script_url); |
| 388 if (!script.IsNull()) { | 389 if (!script.IsNull()) { |
| 389 break; | 390 break; |
| 390 } | 391 } |
| 391 lib = lib.next_registered(); | 392 lib = lib.next_registered(); |
| 392 } | 393 } |
| 393 if (script.IsNull()) { | 394 if (script.IsNull()) { |
| 394 return NULL; | 395 return NULL; |
| 395 } | 396 } |
| 396 intptr_t token_index_at_line = script.TokenIndexAtLine(line_number); | 397 intptr_t token_index_at_line = script.TokenIndexAtLine(line_number); |
| 397 if (token_index_at_line < 0) { | 398 if (token_index_at_line < 0) { |
| 398 // Script does not contain the given line number. | 399 // Script does not contain the given line number. |
| 399 return NULL; | 400 return NULL; |
| 400 } | 401 } |
| 401 const Function& func = | 402 const Function& func = |
| 402 Function::Handle(lib.LookupFunctionInScript(script, token_index_at_line)); | 403 Function::Handle(lib.LookupFunctionInScript(script, token_index_at_line)); |
| 403 if (func.IsNull()) { | 404 if (func.IsNull()) { |
| 404 return NULL; | 405 return NULL; |
| 405 } | 406 } |
| 406 return SetBreakpoint(func, token_index_at_line); | 407 return SetBreakpoint(func, token_index_at_line); |
| 407 } | 408 } |
| 408 | 409 |
| 409 | 410 |
| 411 static RawArray* MakeNameValueList(const GrowableArray<Object*>& pairs) { |
| 412 int pairs_len = pairs.length(); |
| 413 ASSERT(pairs_len % 2 == 0); |
| 414 const Array& list = Array::Handle(Array::New(pairs_len)); |
| 415 for (int i = 0; i < pairs_len; i++) { |
| 416 list.SetAt(i, *pairs[i]); |
| 417 } |
| 418 return list.raw(); |
| 419 } |
| 420 |
| 421 |
| 422 // TODO(hausner): Merge some of this functionality with the code in |
| 423 // dart_api_impl.cc. |
| 424 RawObject* Debugger::GetInstanceField(const Class& cls, |
| 425 const String& field_name, |
| 426 const Instance& object) { |
| 427 const Function& getter_func = |
| 428 Function::Handle(cls.LookupGetterFunction(field_name)); |
| 429 ASSERT(!getter_func.IsNull()); |
| 430 |
| 431 Object& result = Object::Handle(); |
| 432 LongJump* base = isolate_->long_jump_base(); |
| 433 LongJump jump; |
| 434 isolate_->set_long_jump_base(&jump); |
| 435 if (setjmp(*jump.Set()) == 0) { |
| 436 GrowableArray<const Object*> noArguments; |
| 437 const Array& noArgumentNames = Array::Handle(); |
| 438 result = DartEntry::InvokeDynamic(object, getter_func, |
| 439 noArguments, noArgumentNames); |
| 440 } else { |
| 441 result = isolate_->object_store()->sticky_error(); |
| 442 } |
| 443 isolate_->set_long_jump_base(base); |
| 444 return result.raw(); |
| 445 } |
| 446 |
| 447 |
| 448 RawObject* Debugger::GetStaticField(const Class& cls, |
| 449 const String& field_name) { |
| 450 const Function& getter_func = |
| 451 Function::Handle(cls.LookupGetterFunction(field_name)); |
| 452 ASSERT(!getter_func.IsNull()); |
| 453 |
| 454 Object& result = Object::Handle(); |
| 455 LongJump* base = isolate_->long_jump_base(); |
| 456 LongJump jump; |
| 457 isolate_->set_long_jump_base(&jump); |
| 458 if (setjmp(*jump.Set()) == 0) { |
| 459 GrowableArray<const Object*> noArguments; |
| 460 const Array& noArgumentNames = Array::Handle(); |
| 461 result = DartEntry::InvokeStatic(getter_func, noArguments, noArgumentNames); |
| 462 } else { |
| 463 result = isolate_->object_store()->sticky_error(); |
| 464 } |
| 465 isolate_->set_long_jump_base(base); |
| 466 return result.raw(); |
| 467 } |
| 468 |
| 469 |
| 470 RawArray* Debugger::GetInstanceFields(const Instance& obj) { |
| 471 Class& cls = Class::Handle(obj.clazz()); |
| 472 Array& fields = Array::Handle(); |
| 473 Field& field = Field::Handle(); |
| 474 GrowableArray<Object*> field_list(8); |
| 475 // Iterate over fields in class hierarchy to count all instance fields. |
| 476 int num_fields = 0; |
| 477 while (!cls.IsNull()) { |
| 478 fields = cls.fields(); |
| 479 for (int i = 0; i < fields.Length(); i++) { |
| 480 field ^= fields.At(i); |
| 481 if (!field.is_static()) { |
| 482 String& field_name = String::Handle(field.name()); |
| 483 field_list.Add(&field_name); |
| 484 Object& field_value = Object::Handle(); |
| 485 field_value = GetInstanceField(cls, field_name, obj); |
| 486 field_list.Add(&field_value); |
| 487 } |
| 488 } |
| 489 cls = cls.SuperClass(); |
| 490 } |
| 491 return MakeNameValueList(field_list); |
| 492 } |
| 493 |
| 494 |
| 495 RawArray* Debugger::GetStaticFields(const Class& cls) { |
| 496 GrowableArray<Object*> field_list(8); |
| 497 Array& fields = Array::Handle(cls.fields()); |
| 498 Field& field = Field::Handle(); |
| 499 for (int i = 0; i < fields.Length(); i++) { |
| 500 field ^= fields.At(i); |
| 501 if (field.is_static()) { |
| 502 String& field_name = String::Handle(field.name()); |
| 503 Object& field_value = Object::Handle(GetStaticField(cls, field_name)); |
| 504 field_list.Add(&field_name); |
| 505 field_list.Add(&field_value); |
| 506 } |
| 507 } |
| 508 return MakeNameValueList(field_list); |
| 509 } |
| 510 |
| 511 |
| 410 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 512 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 411 ASSERT(visitor != NULL); | 513 ASSERT(visitor != NULL); |
| 412 Breakpoint* bpt = this->breakpoints_; | 514 Breakpoint* bpt = this->breakpoints_; |
| 413 while (bpt != NULL) { | 515 while (bpt != NULL) { |
| 414 bpt->VisitObjectPointers(visitor); | 516 bpt->VisitObjectPointers(visitor); |
| 415 bpt = bpt->next(); | 517 bpt = bpt->next(); |
| 416 } | 518 } |
| 417 } | 519 } |
| 418 | 520 |
| 419 | 521 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 if (bp_handler_ != NULL) { | 571 if (bp_handler_ != NULL) { |
| 470 (*bp_handler_)(bpt, stack_trace); | 572 (*bp_handler_)(bpt, stack_trace); |
| 471 } | 573 } |
| 472 } | 574 } |
| 473 | 575 |
| 474 | 576 |
| 475 void Debugger::Initialize(Isolate* isolate) { | 577 void Debugger::Initialize(Isolate* isolate) { |
| 476 if (initialized_) { | 578 if (initialized_) { |
| 477 return; | 579 return; |
| 478 } | 580 } |
| 581 isolate_ = isolate; |
| 479 initialized_ = true; | 582 initialized_ = true; |
| 480 SetBreakpointHandler(DefaultBreakpointHandler); | 583 SetBreakpointHandler(DefaultBreakpointHandler); |
| 481 } | 584 } |
| 482 | 585 |
| 483 | 586 |
| 484 Breakpoint* Debugger::GetBreakpoint(uword breakpoint_address) { | 587 Breakpoint* Debugger::GetBreakpoint(uword breakpoint_address) { |
| 485 Breakpoint* bpt = this->breakpoints_; | 588 Breakpoint* bpt = this->breakpoints_; |
| 486 while (bpt != NULL) { | 589 while (bpt != NULL) { |
| 487 if (bpt->pc() == breakpoint_address) { | 590 if (bpt->pc() == breakpoint_address) { |
| 488 return bpt; | 591 return bpt; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 | 633 |
| 531 | 634 |
| 532 void Debugger::RegisterBreakpoint(Breakpoint* bpt) { | 635 void Debugger::RegisterBreakpoint(Breakpoint* bpt) { |
| 533 ASSERT(bpt->next() == NULL); | 636 ASSERT(bpt->next() == NULL); |
| 534 bpt->set_next(this->breakpoints_); | 637 bpt->set_next(this->breakpoints_); |
| 535 this->breakpoints_ = bpt; | 638 this->breakpoints_ = bpt; |
| 536 } | 639 } |
| 537 | 640 |
| 538 | 641 |
| 539 } // namespace dart | 642 } // namespace dart |
| OLD | NEW |