OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 | 8 |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 end_token_pos_(end_token_pos), | 77 end_token_pos_(end_token_pos), |
78 is_resolved_(false), | 78 is_resolved_(false), |
79 next_(NULL), | 79 next_(NULL), |
80 conditions_(NULL), | 80 conditions_(NULL), |
81 requested_line_number_(requested_line_number), | 81 requested_line_number_(requested_line_number), |
82 requested_column_number_(requested_column_number), | 82 requested_column_number_(requested_column_number), |
83 function_(Function::null()), | 83 function_(Function::null()), |
84 line_number_(-1), | 84 line_number_(-1), |
85 column_number_(-1) { | 85 column_number_(-1) { |
86 ASSERT(!script.IsNull()); | 86 ASSERT(!script.IsNull()); |
87 ASSERT(token_pos_ >= 0); | 87 ASSERT(Token::IsReal(token_pos_)); |
88 } | 88 } |
89 | 89 |
90 // Create a latent breakpoint at given url and line number. | 90 // Create a latent breakpoint at given url and line number. |
91 BreakpointLocation::BreakpointLocation(const String& url, | 91 BreakpointLocation::BreakpointLocation(const String& url, |
92 intptr_t requested_line_number, | 92 intptr_t requested_line_number, |
93 intptr_t requested_column_number) | 93 intptr_t requested_column_number) |
94 : script_(Script::null()), | 94 : script_(Script::null()), |
95 url_(url.raw()), | 95 url_(url.raw()), |
96 token_pos_(Scanner::kNoSourcePos), | 96 token_pos_(Token::kNoSourcePos), |
97 end_token_pos_(Scanner::kNoSourcePos), | 97 end_token_pos_(Token::kNoSourcePos), |
98 is_resolved_(false), | 98 is_resolved_(false), |
99 next_(NULL), | 99 next_(NULL), |
100 conditions_(NULL), | 100 conditions_(NULL), |
101 requested_line_number_(requested_line_number), | 101 requested_line_number_(requested_line_number), |
102 requested_column_number_(requested_column_number), | 102 requested_column_number_(requested_column_number), |
103 function_(Function::null()), | 103 function_(Function::null()), |
104 line_number_(-1), | 104 line_number_(-1), |
105 column_number_(-1) { | 105 column_number_(-1) { |
106 ASSERT(requested_line_number_ >= 0); | 106 ASSERT(requested_line_number_ >= 0); |
107 } | 107 } |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 uword fp, | 232 uword fp, |
233 uword sp, | 233 uword sp, |
234 const Code& code, | 234 const Code& code, |
235 const Array& deopt_frame, | 235 const Array& deopt_frame, |
236 intptr_t deopt_frame_offset) | 236 intptr_t deopt_frame_offset) |
237 : pc_(pc), fp_(fp), sp_(sp), | 237 : pc_(pc), fp_(fp), sp_(sp), |
238 ctx_(Context::ZoneHandle()), | 238 ctx_(Context::ZoneHandle()), |
239 code_(Code::ZoneHandle(code.raw())), | 239 code_(Code::ZoneHandle(code.raw())), |
240 function_(Function::ZoneHandle(code.function())), | 240 function_(Function::ZoneHandle(code.function())), |
241 token_pos_initialized_(false), | 241 token_pos_initialized_(false), |
242 token_pos_(Scanner::kNoSourcePos), | 242 token_pos_(Token::kNoSourcePos), |
243 try_index_(-1), | 243 try_index_(-1), |
244 line_number_(-1), | 244 line_number_(-1), |
245 column_number_(-1), | 245 column_number_(-1), |
246 context_level_(-1), | 246 context_level_(-1), |
247 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), | 247 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), |
248 deopt_frame_offset_(deopt_frame_offset), | 248 deopt_frame_offset_(deopt_frame_offset), |
249 vars_initialized_(false), | 249 vars_initialized_(false), |
250 var_descriptors_(LocalVarDescriptors::ZoneHandle()), | 250 var_descriptors_(LocalVarDescriptors::ZoneHandle()), |
251 desc_indices_(8), | 251 desc_indices_(8), |
252 pc_desc_(PcDescriptors::ZoneHandle()) { | 252 pc_desc_(PcDescriptors::ZoneHandle()) { |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 pc_desc_ = code().pc_descriptors(); | 559 pc_desc_ = code().pc_descriptors(); |
560 ASSERT(!pc_desc_.IsNull()); | 560 ASSERT(!pc_desc_.IsNull()); |
561 } | 561 } |
562 } | 562 } |
563 | 563 |
564 | 564 |
565 // Compute token_pos_ and try_index_ and token_pos_initialized_. | 565 // Compute token_pos_ and try_index_ and token_pos_initialized_. |
566 intptr_t ActivationFrame::TokenPos() { | 566 intptr_t ActivationFrame::TokenPos() { |
567 if (!token_pos_initialized_) { | 567 if (!token_pos_initialized_) { |
568 token_pos_initialized_ = true; | 568 token_pos_initialized_ = true; |
569 token_pos_ = Scanner::kNoSourcePos; | 569 token_pos_ = Token::kNoSourcePos; |
570 GetPcDescriptors(); | 570 GetPcDescriptors(); |
571 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); | 571 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); |
572 uword pc_offset = pc_ - code().EntryPoint(); | 572 uword pc_offset = pc_ - code().EntryPoint(); |
573 while (iter.MoveNext()) { | 573 while (iter.MoveNext()) { |
574 if (iter.PcOffset() == pc_offset) { | 574 if (iter.PcOffset() == pc_offset) { |
575 try_index_ = iter.TryIndex(); | 575 try_index_ = iter.TryIndex(); |
576 token_pos_ = iter.TokenPos(); | 576 token_pos_ = iter.TokenPos(); |
577 break; | 577 break; |
578 } | 578 } |
579 } | 579 } |
580 } | 580 } |
581 return token_pos_; | 581 return token_pos_; |
582 } | 582 } |
583 | 583 |
584 | 584 |
585 intptr_t ActivationFrame::TryIndex() { | 585 intptr_t ActivationFrame::TryIndex() { |
586 if (!token_pos_initialized_) { | 586 if (!token_pos_initialized_) { |
587 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. | 587 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. |
588 } | 588 } |
589 return try_index_; | 589 return try_index_; |
590 } | 590 } |
591 | 591 |
592 | 592 |
593 intptr_t ActivationFrame::LineNumber() { | 593 intptr_t ActivationFrame::LineNumber() { |
594 // Compute line number lazily since it causes scanning of the script. | 594 // Compute line number lazily since it causes scanning of the script. |
595 if ((line_number_ < 0) && (TokenPos() >= 0)) { | 595 if ((line_number_ < 0) && Token::IsReal(TokenPos())) { |
| 596 const intptr_t token_pos = TokenPos(); |
596 const Script& script = Script::Handle(SourceScript()); | 597 const Script& script = Script::Handle(SourceScript()); |
597 script.GetTokenLocation(TokenPos(), &line_number_, NULL); | 598 script.GetTokenLocation(token_pos, &line_number_, NULL); |
598 } | 599 } |
599 return line_number_; | 600 return line_number_; |
600 } | 601 } |
601 | 602 |
602 | 603 |
603 intptr_t ActivationFrame::ColumnNumber() { | 604 intptr_t ActivationFrame::ColumnNumber() { |
604 // Compute column number lazily since it causes scanning of the script. | 605 // Compute column number lazily since it causes scanning of the script. |
605 if ((column_number_ < 0) && (TokenPos() >= 0)) { | 606 if ((column_number_ < 0) && Token::IsReal(TokenPos())) { |
| 607 const intptr_t token_pos = TokenPos(); |
606 const Script& script = Script::Handle(SourceScript()); | 608 const Script& script = Script::Handle(SourceScript()); |
607 if (script.HasSource()) { | 609 if (script.HasSource()) { |
608 script.GetTokenLocation(TokenPos(), &line_number_, &column_number_); | 610 script.GetTokenLocation(token_pos, &line_number_, &column_number_); |
609 } else { | 611 } else { |
610 column_number_ = -1; | 612 column_number_ = -1; |
611 } | 613 } |
612 } | 614 } |
613 return column_number_; | 615 return column_number_; |
614 } | 616 } |
615 | 617 |
616 | 618 |
617 void ActivationFrame::GetVarDescriptors() { | 619 void ActivationFrame::GetVarDescriptors() { |
618 if (var_descriptors_.IsNull()) { | 620 if (var_descriptors_.IsNull()) { |
(...skipping 28 matching lines...) Expand all Loading... |
647 // for the code position of the frame? For now say we are at context | 649 // for the code position of the frame? For now say we are at context |
648 // level 0. | 650 // level 0. |
649 TokenPos(); | 651 TokenPos(); |
650 if (token_pos_ == -1) { | 652 if (token_pos_ == -1) { |
651 // No PcDescriptor. | 653 // No PcDescriptor. |
652 return context_level_; | 654 return context_level_; |
653 } | 655 } |
654 ASSERT(!pc_desc_.IsNull()); | 656 ASSERT(!pc_desc_.IsNull()); |
655 intptr_t innermost_begin_pos = 0; | 657 intptr_t innermost_begin_pos = 0; |
656 intptr_t activation_token_pos = TokenPos(); | 658 intptr_t activation_token_pos = TokenPos(); |
657 ASSERT(activation_token_pos >= 0); | 659 ASSERT(Token::IsReal(activation_token_pos)); |
658 GetVarDescriptors(); | 660 GetVarDescriptors(); |
659 intptr_t var_desc_len = var_descriptors_.Length(); | 661 intptr_t var_desc_len = var_descriptors_.Length(); |
660 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 662 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
661 RawLocalVarDescriptors::VarInfo var_info; | 663 RawLocalVarDescriptors::VarInfo var_info; |
662 var_descriptors_.GetInfo(cur_idx, &var_info); | 664 var_descriptors_.GetInfo(cur_idx, &var_info); |
663 const int8_t kind = var_info.kind(); | 665 const int8_t kind = var_info.kind(); |
664 if ((kind == RawLocalVarDescriptors::kContextLevel) && | 666 if ((kind == RawLocalVarDescriptors::kContextLevel) && |
665 (var_info.begin_pos <= activation_token_pos) && | 667 (var_info.begin_pos <= activation_token_pos) && |
666 (activation_token_pos < var_info.end_pos)) { | 668 (activation_token_pos < var_info.end_pos)) { |
667 // This var_descriptors_ entry is a context scope which is in scope | 669 // This var_descriptors_ entry is a context scope which is in scope |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 } | 762 } |
761 | 763 |
762 | 764 |
763 void ActivationFrame::GetDescIndices() { | 765 void ActivationFrame::GetDescIndices() { |
764 if (vars_initialized_) { | 766 if (vars_initialized_) { |
765 return; | 767 return; |
766 } | 768 } |
767 GetVarDescriptors(); | 769 GetVarDescriptors(); |
768 | 770 |
769 intptr_t activation_token_pos = TokenPos(); | 771 intptr_t activation_token_pos = TokenPos(); |
770 if (activation_token_pos < 0) { | 772 if (!Token::IsDebugPause(activation_token_pos)) { |
771 // We don't have a token position for this frame, so can't determine | 773 // We don't have a token position for this frame, so can't determine |
772 // which variables are visible. | 774 // which variables are visible. |
773 vars_initialized_ = true; | 775 vars_initialized_ = true; |
774 return; | 776 return; |
775 } | 777 } |
776 | 778 |
777 GrowableArray<String*> var_names(8); | 779 GrowableArray<String*> var_names(8); |
778 intptr_t var_desc_len = var_descriptors_.Length(); | 780 intptr_t var_desc_len = var_descriptors_.Length(); |
779 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 781 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
780 ASSERT(var_names.length() == desc_indices_.length()); | 782 ASSERT(var_names.length() == desc_indices_.length()); |
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1733 ASSERT(!code.IsNull()); | 1735 ASSERT(!code.IsNull()); |
1734 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 1736 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
1735 | 1737 |
1736 // First pass: find the safe point which is closest to the beginning | 1738 // First pass: find the safe point which is closest to the beginning |
1737 // of the given token range. | 1739 // of the given token range. |
1738 intptr_t best_fit_pos = INT_MAX; | 1740 intptr_t best_fit_pos = INT_MAX; |
1739 intptr_t best_column = INT_MAX; | 1741 intptr_t best_column = INT_MAX; |
1740 PcDescriptors::Iterator iter(desc, kSafepointKind); | 1742 PcDescriptors::Iterator iter(desc, kSafepointKind); |
1741 while (iter.MoveNext()) { | 1743 while (iter.MoveNext()) { |
1742 const intptr_t pos = iter.TokenPos(); | 1744 const intptr_t pos = iter.TokenPos(); |
1743 if ((pos < 0) || | 1745 if ((!Token::IsReal(pos)) || |
1744 (pos < requested_token_pos) || | 1746 (pos < requested_token_pos) || |
1745 (pos > last_token_pos)) { | 1747 (pos > last_token_pos)) { |
1746 // Token is not in the target range. | 1748 // Token is not in the target range. |
1747 continue; | 1749 continue; |
1748 } | 1750 } |
1749 | 1751 |
1750 intptr_t token_start_column = -1; | 1752 intptr_t token_start_column = -1; |
1751 if (requested_column >= 0) { | 1753 if (requested_column >= 0) { |
1752 intptr_t ignored = -1; | 1754 intptr_t ignored = -1; |
1753 intptr_t token_len = -1; | 1755 intptr_t token_len = -1; |
(...skipping 25 matching lines...) Expand all Loading... |
1779 // was specified) and has the lowest code address. | 1781 // was specified) and has the lowest code address. |
1780 if (best_fit_pos != INT_MAX) { | 1782 if (best_fit_pos != INT_MAX) { |
1781 const Script& script = Script::Handle(func.script()); | 1783 const Script& script = Script::Handle(func.script()); |
1782 const TokenStream& tokens = TokenStream::Handle(script.tokens()); | 1784 const TokenStream& tokens = TokenStream::Handle(script.tokens()); |
1783 const intptr_t begin_pos = best_fit_pos; | 1785 const intptr_t begin_pos = best_fit_pos; |
1784 const intptr_t end_of_line_pos = LastTokenOnLine(tokens, begin_pos); | 1786 const intptr_t end_of_line_pos = LastTokenOnLine(tokens, begin_pos); |
1785 uword lowest_pc_offset = kUwordMax; | 1787 uword lowest_pc_offset = kUwordMax; |
1786 PcDescriptors::Iterator iter(desc, kSafepointKind); | 1788 PcDescriptors::Iterator iter(desc, kSafepointKind); |
1787 while (iter.MoveNext()) { | 1789 while (iter.MoveNext()) { |
1788 const intptr_t pos = iter.TokenPos(); | 1790 const intptr_t pos = iter.TokenPos(); |
1789 if ((pos < 0) || | 1791 if ((!Token::IsReal(pos)) || |
1790 (pos < begin_pos) || | 1792 (pos < begin_pos) || |
1791 (pos > end_of_line_pos)) { | 1793 (pos > end_of_line_pos)) { |
1792 // Token is not on same line as best fit. | 1794 // Token is not on same line as best fit. |
1793 continue; | 1795 continue; |
1794 } | 1796 } |
1795 | 1797 |
1796 if (requested_column >= 0) { | 1798 if (requested_column >= 0) { |
1797 intptr_t ignored = -1; | 1799 intptr_t ignored = -1; |
1798 intptr_t token_start_column = -1; | 1800 intptr_t token_start_column = -1; |
1799 // We look for other tokens at the best column in case there | 1801 // We look for other tokens at the best column in case there |
(...skipping 14 matching lines...) Expand all Loading... |
1814 } | 1816 } |
1815 | 1817 |
1816 // We didn't find a safe point in the given token range. Try and | 1818 // We didn't find a safe point in the given token range. Try and |
1817 // find a safe point in the remaining source code of the function. | 1819 // find a safe point in the remaining source code of the function. |
1818 // Since we have moved to the next line of the function, we no | 1820 // Since we have moved to the next line of the function, we no |
1819 // longer are requesting a specific column number. | 1821 // longer are requesting a specific column number. |
1820 if (last_token_pos < func.end_token_pos()) { | 1822 if (last_token_pos < func.end_token_pos()) { |
1821 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(), | 1823 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(), |
1822 -1 /* no column */); | 1824 -1 /* no column */); |
1823 } | 1825 } |
1824 return -1; | 1826 return Token::kNoSourcePos; |
1825 } | 1827 } |
1826 | 1828 |
1827 | 1829 |
1828 void Debugger::MakeCodeBreakpointAt(const Function& func, | 1830 void Debugger::MakeCodeBreakpointAt(const Function& func, |
1829 BreakpointLocation* loc) { | 1831 BreakpointLocation* loc) { |
1830 ASSERT(loc->token_pos_ >= 0); | 1832 ASSERT(Token::IsReal(loc->token_pos_)); |
1831 ASSERT((loc != NULL) && loc->IsResolved()); | 1833 ASSERT((loc != NULL) && loc->IsResolved()); |
1832 ASSERT(!func.HasOptimizedCode()); | 1834 ASSERT(!func.HasOptimizedCode()); |
1833 Code& code = Code::Handle(func.unoptimized_code()); | 1835 Code& code = Code::Handle(func.unoptimized_code()); |
1834 ASSERT(!code.IsNull()); | 1836 ASSERT(!code.IsNull()); |
1835 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 1837 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
1836 uword lowest_pc_offset = kUwordMax; | 1838 uword lowest_pc_offset = kUwordMax; |
1837 RawPcDescriptors::Kind lowest_kind = RawPcDescriptors::kAnyKind; | 1839 RawPcDescriptors::Kind lowest_kind = RawPcDescriptors::kAnyKind; |
1838 // Find the safe point with the lowest compiled code address | 1840 // Find the safe point with the lowest compiled code address |
1839 // that maps to the token position of the source breakpoint. | 1841 // that maps to the token position of the source breakpoint. |
1840 PcDescriptors::Iterator iter(desc, kSafepointKind); | 1842 PcDescriptors::Iterator iter(desc, kSafepointKind); |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2235 } | 2237 } |
2236 if (scripts.Length() > 1) { | 2238 if (scripts.Length() > 1) { |
2237 if (FLAG_verbose_debug) { | 2239 if (FLAG_verbose_debug) { |
2238 OS::Print("Multiple scripts match url '%s'\n", script_url.ToCString()); | 2240 OS::Print("Multiple scripts match url '%s'\n", script_url.ToCString()); |
2239 } | 2241 } |
2240 return NULL; | 2242 return NULL; |
2241 } | 2243 } |
2242 script ^= scripts.At(0); | 2244 script ^= scripts.At(0); |
2243 intptr_t first_token_idx, last_token_idx; | 2245 intptr_t first_token_idx, last_token_idx; |
2244 script.TokenRangeAtLine(line_number, &first_token_idx, &last_token_idx); | 2246 script.TokenRangeAtLine(line_number, &first_token_idx, &last_token_idx); |
2245 if (first_token_idx < 0) { | 2247 if (!Token::IsReal(first_token_idx)) { |
2246 // Script does not contain the given line number. | 2248 // Script does not contain the given line number. |
2247 if (FLAG_verbose_debug) { | 2249 if (FLAG_verbose_debug) { |
2248 OS::Print("Script '%s' does not contain line number %" Pd "\n", | 2250 OS::Print("Script '%s' does not contain line number %" Pd "\n", |
2249 script_url.ToCString(), line_number); | 2251 script_url.ToCString(), line_number); |
2250 } | 2252 } |
2251 return NULL; | 2253 return NULL; |
2252 } else if (last_token_idx < 0) { | 2254 } else if (!Token::IsReal(last_token_idx)) { |
2253 // Line does not contain any tokens. | 2255 // Line does not contain any tokens. |
2254 if (FLAG_verbose_debug) { | 2256 if (FLAG_verbose_debug) { |
2255 OS::Print("No executable code at line %" Pd " in '%s'\n", | 2257 OS::Print("No executable code at line %" Pd " in '%s'\n", |
2256 line_number, script_url.ToCString()); | 2258 line_number, script_url.ToCString()); |
2257 } | 2259 } |
2258 return NULL; | 2260 return NULL; |
2259 } | 2261 } |
2260 | 2262 |
2261 BreakpointLocation* bpt = NULL; | 2263 BreakpointLocation* bpt = NULL; |
2262 ASSERT(first_token_idx <= last_token_idx); | 2264 ASSERT(first_token_idx <= last_token_idx); |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2534 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace) { | 2536 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace) { |
2535 stepping_fp_ = 0; | 2537 stepping_fp_ = 0; |
2536 if (resume_action_ == kSingleStep) { | 2538 if (resume_action_ == kSingleStep) { |
2537 // When single stepping, we need to deoptimize because we might be | 2539 // When single stepping, we need to deoptimize because we might be |
2538 // stepping into optimized code. This happens in particular if | 2540 // stepping into optimized code. This happens in particular if |
2539 // the isolate has been interrupted, but can happen in other cases | 2541 // the isolate has been interrupted, but can happen in other cases |
2540 // as well. We need to deoptimize the world in case we are about | 2542 // as well. We need to deoptimize the world in case we are about |
2541 // to call an optimized function. | 2543 // to call an optimized function. |
2542 DeoptimizeWorld(); | 2544 DeoptimizeWorld(); |
2543 isolate_->set_single_step(true); | 2545 isolate_->set_single_step(true); |
| 2546 if (FLAG_verbose_debug) { |
| 2547 OS::Print("HandleSteppingRequest- kSingleStep\n"); |
| 2548 } |
2544 } else if (resume_action_ == kStepOver) { | 2549 } else if (resume_action_ == kStepOver) { |
2545 DeoptimizeWorld(); | 2550 DeoptimizeWorld(); |
2546 isolate_->set_single_step(true); | 2551 isolate_->set_single_step(true); |
2547 ASSERT(stack_trace->Length() > 0); | 2552 ASSERT(stack_trace->Length() > 0); |
2548 stepping_fp_ = stack_trace->FrameAt(0)->fp(); | 2553 stepping_fp_ = stack_trace->FrameAt(0)->fp(); |
| 2554 if (FLAG_verbose_debug) { |
| 2555 OS::Print("HandleSteppingRequest- kStepOver %" Px "\n", stepping_fp_); |
| 2556 } |
2549 } else if (resume_action_ == kStepOut) { | 2557 } else if (resume_action_ == kStepOut) { |
2550 DeoptimizeWorld(); | 2558 DeoptimizeWorld(); |
2551 isolate_->set_single_step(true); | 2559 isolate_->set_single_step(true); |
2552 // Find topmost caller that is debuggable. | 2560 // Find topmost caller that is debuggable. |
2553 for (intptr_t i = 1; i < stack_trace->Length(); i++) { | 2561 for (intptr_t i = 1; i < stack_trace->Length(); i++) { |
2554 ActivationFrame* frame = stack_trace->FrameAt(i); | 2562 ActivationFrame* frame = stack_trace->FrameAt(i); |
2555 if (frame->IsDebuggable()) { | 2563 if (frame->IsDebuggable()) { |
2556 stepping_fp_ = frame->fp(); | 2564 stepping_fp_ = frame->fp(); |
2557 break; | 2565 break; |
2558 } | 2566 } |
2559 } | 2567 } |
| 2568 if (FLAG_verbose_debug) { |
| 2569 OS::Print("HandleSteppingRequest- kStepOut %" Px "\n", stepping_fp_); |
| 2570 } |
2560 } | 2571 } |
2561 } | 2572 } |
2562 | 2573 |
2563 | 2574 |
2564 // static | 2575 // static |
2565 bool Debugger::IsDebuggable(const Function& func) { | 2576 bool Debugger::IsDebuggable(const Function& func) { |
2566 if (!func.is_debuggable()) { | 2577 if (!func.is_debuggable()) { |
2567 return false; | 2578 return false; |
2568 } | 2579 } |
2569 if (ServiceIsolate::IsRunning()) { | 2580 if (ServiceIsolate::IsRunning()) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2634 // We returned from the "interesting frame", there can be no more | 2645 // We returned from the "interesting frame", there can be no more |
2635 // stepping breaks for it. Pause at the next appropriate location | 2646 // stepping breaks for it. Pause at the next appropriate location |
2636 // and let the user set the "interesting" frame again. | 2647 // and let the user set the "interesting" frame again. |
2637 stepping_fp_ = 0; | 2648 stepping_fp_ = 0; |
2638 } | 2649 } |
2639 } | 2650 } |
2640 | 2651 |
2641 if (!frame->IsDebuggable()) { | 2652 if (!frame->IsDebuggable()) { |
2642 return Error::null(); | 2653 return Error::null(); |
2643 } | 2654 } |
2644 if (frame->TokenPos() < 0) { | 2655 if (!Token::IsDebugPause(frame->TokenPos())) { |
2645 return Error::null(); | 2656 return Error::null(); |
2646 } | 2657 } |
2647 | 2658 |
2648 // Don't pause for a single step if there is a breakpoint set | 2659 // Don't pause for a single step if there is a breakpoint set |
2649 // at this location. | 2660 // at this location. |
2650 if (HasActiveBreakpoint(frame->pc())) { | 2661 if (HasActiveBreakpoint(frame->pc())) { |
2651 return Error::null(); | 2662 return Error::null(); |
2652 } | 2663 } |
2653 | 2664 |
2654 if (FLAG_verbose_debug) { | 2665 if (FLAG_verbose_debug) { |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2879 ASSERT(!func.HasOptimizedCode()); | 2890 ASSERT(!func.HasOptimizedCode()); |
2880 | 2891 |
2881 // There is no local function within func that contains the | 2892 // There is no local function within func that contains the |
2882 // breakpoint token position. Resolve the breakpoint if necessary | 2893 // breakpoint token position. Resolve the breakpoint if necessary |
2883 // and set the code breakpoints. | 2894 // and set the code breakpoints. |
2884 if (!loc->IsResolved()) { | 2895 if (!loc->IsResolved()) { |
2885 // Resolve source breakpoint in the newly compiled function. | 2896 // Resolve source breakpoint in the newly compiled function. |
2886 intptr_t bp_pos = | 2897 intptr_t bp_pos = |
2887 ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos(), | 2898 ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos(), |
2888 loc->requested_column_number()); | 2899 loc->requested_column_number()); |
2889 if (bp_pos < 0) { | 2900 if (!Token::IsDebugPause(bp_pos)) { |
2890 if (FLAG_verbose_debug) { | 2901 if (FLAG_verbose_debug) { |
2891 OS::Print("Failed resolving breakpoint for function '%s'\n", | 2902 OS::Print("Failed resolving breakpoint for function '%s'\n", |
2892 String::Handle(func.name()).ToCString()); | 2903 String::Handle(func.name()).ToCString()); |
2893 } | 2904 } |
2894 continue; | 2905 continue; |
2895 } | 2906 } |
2896 intptr_t requested_pos = loc->token_pos(); | 2907 intptr_t requested_pos = loc->token_pos(); |
2897 intptr_t requested_end_pos = loc->end_token_pos(); | 2908 intptr_t requested_end_pos = loc->end_token_pos(); |
2898 loc->SetResolved(func, bp_pos); | 2909 loc->SetResolved(func, bp_pos); |
2899 Breakpoint* bpt = loc->breakpoints(); | 2910 Breakpoint* bpt = loc->breakpoints(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2967 } else { | 2978 } else { |
2968 prev_loc->set_next(loc); | 2979 prev_loc->set_next(loc); |
2969 } | 2980 } |
2970 // Now find the token range at the requested line and make a | 2981 // Now find the token range at the requested line and make a |
2971 // new unresolved source breakpoint. | 2982 // new unresolved source breakpoint. |
2972 intptr_t line_number = matched_loc->requested_line_number(); | 2983 intptr_t line_number = matched_loc->requested_line_number(); |
2973 intptr_t column_number = matched_loc->requested_column_number(); | 2984 intptr_t column_number = matched_loc->requested_column_number(); |
2974 ASSERT(line_number >= 0); | 2985 ASSERT(line_number >= 0); |
2975 intptr_t first_token_pos, last_token_pos; | 2986 intptr_t first_token_pos, last_token_pos; |
2976 script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos); | 2987 script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos); |
2977 if ((first_token_pos < 0) || | 2988 if (!Token::IsDebugPause(first_token_pos) || |
2978 (last_token_pos < 0)) { | 2989 !Token::IsDebugPause(last_token_pos)) { |
2979 // Script does not contain the given line number or there are no | 2990 // Script does not contain the given line number or there are no |
2980 // tokens on the line. Drop the breakpoint silently. | 2991 // tokens on the line. Drop the breakpoint silently. |
2981 Breakpoint* bpt = matched_loc->breakpoints(); | 2992 Breakpoint* bpt = matched_loc->breakpoints(); |
2982 while (bpt != NULL) { | 2993 while (bpt != NULL) { |
2983 if (FLAG_verbose_debug) { | 2994 if (FLAG_verbose_debug) { |
2984 OS::Print("No code found at line %" Pd ": " | 2995 OS::Print("No code found at line %" Pd ": " |
2985 "dropping latent breakpoint %" Pd " in '%s'\n", | 2996 "dropping latent breakpoint %" Pd " in '%s'\n", |
2986 line_number, | 2997 line_number, |
2987 bpt->id(), | 2998 bpt->id(), |
2988 url.ToCString()); | 2999 url.ToCString()); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3243 } | 3254 } |
3244 | 3255 |
3245 | 3256 |
3246 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 3257 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
3247 ASSERT(bpt->next() == NULL); | 3258 ASSERT(bpt->next() == NULL); |
3248 bpt->set_next(code_breakpoints_); | 3259 bpt->set_next(code_breakpoints_); |
3249 code_breakpoints_ = bpt; | 3260 code_breakpoints_ = bpt; |
3250 } | 3261 } |
3251 | 3262 |
3252 } // namespace dart | 3263 } // namespace dart |
OLD | NEW |