OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/debug/debug.h" | 5 #include "src/debug/debug.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 in_debug_event_listener_(false), | 52 in_debug_event_listener_(false), |
53 break_on_exception_(false), | 53 break_on_exception_(false), |
54 break_on_uncaught_exception_(false), | 54 break_on_uncaught_exception_(false), |
55 side_effect_check_failed_(false), | 55 side_effect_check_failed_(false), |
56 debug_info_list_(NULL), | 56 debug_info_list_(NULL), |
57 feature_tracker_(isolate), | 57 feature_tracker_(isolate), |
58 isolate_(isolate) { | 58 isolate_(isolate) { |
59 ThreadInit(); | 59 ThreadInit(); |
60 } | 60 } |
61 | 61 |
62 BreakLocation BreakLocation::FromFrame(StandardFrame* frame) { | 62 BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info, |
63 // TODO(clemensh): Handle Wasm frames. | 63 JavaScriptFrame* frame) { |
64 DCHECK(!frame->is_wasm()); | 64 auto summary = FrameSummary::GetTop(frame).AsJavaScript(); |
65 | |
66 auto summary = FrameSummary::GetFirst(frame).AsJavaScript(); | |
67 int offset = summary.code_offset(); | 65 int offset = summary.code_offset(); |
68 Handle<AbstractCode> abstract_code = summary.abstract_code(); | 66 Handle<AbstractCode> abstract_code = summary.abstract_code(); |
69 if (abstract_code->IsCode()) offset = offset - 1; | 67 if (abstract_code->IsCode()) offset = offset - 1; |
70 Handle<DebugInfo> debug_info(summary.function()->shared()->GetDebugInfo()); | |
71 auto it = BreakIterator::GetIterator(debug_info, abstract_code); | 68 auto it = BreakIterator::GetIterator(debug_info, abstract_code); |
72 it->SkipTo(BreakIndexFromCodeOffset(debug_info, abstract_code, offset)); | 69 it->SkipTo(BreakIndexFromCodeOffset(debug_info, abstract_code, offset)); |
73 return it->GetBreakLocation(); | 70 return it->GetBreakLocation(); |
74 } | 71 } |
75 | 72 |
76 void BreakLocation::AllAtCurrentStatement(Handle<DebugInfo> debug_info, | 73 void BreakLocation::AllAtCurrentStatement(Handle<DebugInfo> debug_info, |
77 JavaScriptFrame* frame, | 74 JavaScriptFrame* frame, |
78 List<BreakLocation>* result_out) { | 75 List<BreakLocation>* result_out) { |
79 auto summary = FrameSummary::GetFirst(frame).AsJavaScript(); | 76 auto summary = FrameSummary::GetTop(frame).AsJavaScript(); |
80 int offset = summary.code_offset(); | 77 int offset = summary.code_offset(); |
81 Handle<AbstractCode> abstract_code = summary.abstract_code(); | 78 Handle<AbstractCode> abstract_code = summary.abstract_code(); |
82 if (abstract_code->IsCode()) offset = offset - 1; | 79 if (abstract_code->IsCode()) offset = offset - 1; |
83 int statement_position; | 80 int statement_position; |
84 { | 81 { |
85 auto it = BreakIterator::GetIterator(debug_info, abstract_code); | 82 auto it = BreakIterator::GetIterator(debug_info, abstract_code); |
86 it->SkipTo(BreakIndexFromCodeOffset(debug_info, abstract_code, offset)); | 83 it->SkipTo(BreakIndexFromCodeOffset(debug_info, abstract_code, offset)); |
87 statement_position = it->statement_position(); | 84 statement_position = it->statement_position(); |
88 } | 85 } |
89 for (auto it = BreakIterator::GetIterator(debug_info, abstract_code); | 86 for (auto it = BreakIterator::GetIterator(debug_info, abstract_code); |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 DebugScope debug_scope(this); | 511 DebugScope debug_scope(this); |
515 if (debug_scope.failed()) return; | 512 if (debug_scope.failed()) return; |
516 | 513 |
517 // Postpone interrupt during breakpoint processing. | 514 // Postpone interrupt during breakpoint processing. |
518 PostponeInterruptsScope postpone(isolate_); | 515 PostponeInterruptsScope postpone(isolate_); |
519 | 516 |
520 // Return if we fail to retrieve debug info. | 517 // Return if we fail to retrieve debug info. |
521 Handle<JSFunction> function(frame->function()); | 518 Handle<JSFunction> function(frame->function()); |
522 Handle<SharedFunctionInfo> shared(function->shared()); | 519 Handle<SharedFunctionInfo> shared(function->shared()); |
523 if (!EnsureDebugInfo(shared, function)) return; | 520 if (!EnsureDebugInfo(shared, function)) return; |
| 521 Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_); |
524 | 522 |
525 BreakLocation location = BreakLocation::FromFrame(frame); | 523 // Find the break location where execution has stopped. |
| 524 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); |
526 | 525 |
527 // Find actual break points, if any, and trigger debug break event. | 526 // Find actual break points, if any, and trigger debug break event. |
528 MaybeHandle<FixedArray> break_points_hit; | 527 MaybeHandle<FixedArray> break_points_hit = |
529 if (break_points_active()) { | 528 CheckBreakPoints(debug_info, &location); |
530 // Get the debug info, which must exist if we reach here. | |
531 Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_); | |
532 | |
533 break_points_hit = CheckBreakPoints(debug_info, &location); | |
534 } | |
535 | |
536 if (!break_points_hit.is_null()) { | 529 if (!break_points_hit.is_null()) { |
537 // Clear all current stepping setup. | 530 // Clear all current stepping setup. |
538 ClearStepping(); | 531 ClearStepping(); |
539 // Notify the debug event listeners. | 532 // Notify the debug event listeners. |
540 Handle<JSArray> jsarr = isolate_->factory()->NewJSArrayWithElements( | 533 Handle<JSArray> jsarr = isolate_->factory()->NewJSArrayWithElements( |
541 break_points_hit.ToHandleChecked()); | 534 break_points_hit.ToHandleChecked()); |
542 OnDebugBreak(jsarr, false); | 535 OnDebugBreak(jsarr, false); |
543 return; | 536 return; |
544 } | 537 } |
545 | 538 |
(...skipping 12 matching lines...) Expand all Loading... |
558 if (current_fp < target_fp) return; | 551 if (current_fp < target_fp) return; |
559 step_break = true; | 552 step_break = true; |
560 break; | 553 break; |
561 case StepNext: | 554 case StepNext: |
562 // Step next should not break in a deeper frame. | 555 // Step next should not break in a deeper frame. |
563 if (current_fp < target_fp) return; | 556 if (current_fp < target_fp) return; |
564 // For step-next, a tail call is like a return and should break. | 557 // For step-next, a tail call is like a return and should break. |
565 step_break = location.IsTailCall(); | 558 step_break = location.IsTailCall(); |
566 // Fall through. | 559 // Fall through. |
567 case StepIn: { | 560 case StepIn: { |
568 FrameSummary summary = FrameSummary::GetFirst(frame); | 561 FrameSummary summary = FrameSummary::GetTop(frame); |
569 step_break = step_break || location.IsReturn() || current_fp != last_fp || | 562 step_break = step_break || location.IsReturn() || current_fp != last_fp || |
570 thread_local_.last_statement_position_ != | 563 thread_local_.last_statement_position_ != |
571 summary.SourceStatementPosition(); | 564 summary.SourceStatementPosition(); |
572 break; | 565 break; |
573 } | 566 } |
574 case StepFrame: | 567 case StepFrame: |
575 step_break = current_fp != last_fp; | 568 step_break = current_fp != last_fp; |
576 break; | 569 break; |
577 } | 570 } |
578 | 571 |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 // Step out: Find the calling JavaScript frame and flood it with | 1000 // Step out: Find the calling JavaScript frame and flood it with |
1008 // breakpoints. | 1001 // breakpoints. |
1009 frames_it.Advance(); | 1002 frames_it.Advance(); |
1010 // Fill the function to return to with one-shot break points. | 1003 // Fill the function to return to with one-shot break points. |
1011 JSFunction* function = frames_it.frame()->function(); | 1004 JSFunction* function = frames_it.frame()->function(); |
1012 FloodWithOneShot(Handle<JSFunction>(function)); | 1005 FloodWithOneShot(Handle<JSFunction>(function)); |
1013 return; | 1006 return; |
1014 } | 1007 } |
1015 | 1008 |
1016 // Get the debug info (create it if it does not exist). | 1009 // Get the debug info (create it if it does not exist). |
1017 auto summary = FrameSummary::GetFirst(frame).AsJavaScript(); | 1010 auto summary = FrameSummary::GetTop(frame).AsJavaScript(); |
1018 Handle<JSFunction> function(summary.function()); | 1011 Handle<JSFunction> function(summary.function()); |
1019 Handle<SharedFunctionInfo> shared(function->shared()); | 1012 Handle<SharedFunctionInfo> shared(function->shared()); |
1020 if (!EnsureDebugInfo(shared, function)) { | 1013 if (!EnsureDebugInfo(shared, function)) { |
1021 // Return if ensuring debug info failed. | 1014 // Return if ensuring debug info failed. |
1022 return; | 1015 return; |
1023 } | 1016 } |
1024 | 1017 |
1025 BreakLocation location = BreakLocation::FromFrame(frame); | 1018 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |
| 1019 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); |
1026 | 1020 |
1027 // Any step at a return is a step-out. | 1021 // Any step at a return is a step-out. |
1028 if (location.IsReturn()) step_action = StepOut; | 1022 if (location.IsReturn()) step_action = StepOut; |
1029 // A step-next at a tail call is a step-out. | 1023 // A step-next at a tail call is a step-out. |
1030 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut; | 1024 if (location.IsTailCall() && step_action == StepNext) step_action = StepOut; |
1031 | 1025 |
1032 thread_local_.last_statement_position_ = | 1026 thread_local_.last_statement_position_ = |
1033 summary.abstract_code()->SourceStatementPosition(summary.code_offset()); | 1027 summary.abstract_code()->SourceStatementPosition(summary.code_offset()); |
1034 thread_local_.last_fp_ = frame->UnpaddedFP(); | 1028 thread_local_.last_fp_ = frame->UnpaddedFP(); |
1035 // No longer perform the current async step. | 1029 // No longer perform the current async step. |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1582 after_break_target_ = NULL; | 1576 after_break_target_ = NULL; |
1583 if (!LiveEdit::SetAfterBreakTarget(this)) { | 1577 if (!LiveEdit::SetAfterBreakTarget(this)) { |
1584 // Continue just after the slot. | 1578 // Continue just after the slot. |
1585 after_break_target_ = frame->pc(); | 1579 after_break_target_ = frame->pc(); |
1586 } | 1580 } |
1587 } | 1581 } |
1588 | 1582 |
1589 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { | 1583 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { |
1590 HandleScope scope(isolate_); | 1584 HandleScope scope(isolate_); |
1591 | 1585 |
| 1586 // Get the executing function in which the debug break occurred. |
| 1587 Handle<SharedFunctionInfo> shared(frame->function()->shared()); |
| 1588 |
1592 // With no debug info there are no break points, so we can't be at a return. | 1589 // With no debug info there are no break points, so we can't be at a return. |
1593 if (!frame->function()->shared()->HasDebugInfo()) return false; | 1590 if (!shared->HasDebugInfo()) return false; |
1594 | 1591 |
1595 DCHECK(!frame->is_optimized()); | 1592 DCHECK(!frame->is_optimized()); |
1596 BreakLocation location = BreakLocation::FromFrame(frame); | 1593 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |
| 1594 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); |
1597 return location.IsReturn() || location.IsTailCall(); | 1595 return location.IsReturn() || location.IsTailCall(); |
1598 } | 1596 } |
1599 | 1597 |
1600 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, | 1598 void Debug::FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, |
1601 LiveEditFrameDropMode mode) { | 1599 LiveEditFrameDropMode mode) { |
1602 if (mode != LIVE_EDIT_CURRENTLY_SET_MODE) { | 1600 if (mode != LIVE_EDIT_CURRENTLY_SET_MODE) { |
1603 thread_local_.frame_drop_mode_ = mode; | 1601 thread_local_.frame_drop_mode_ = mode; |
1604 } | 1602 } |
1605 thread_local_.break_frame_id_ = new_break_frame_id; | 1603 thread_local_.break_frame_id_ = new_break_frame_id; |
1606 } | 1604 } |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2280 OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only); | 2278 OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only); |
2281 } | 2279 } |
2282 | 2280 |
2283 #ifdef DEBUG | 2281 #ifdef DEBUG |
2284 void Debug::PrintBreakLocation() { | 2282 void Debug::PrintBreakLocation() { |
2285 if (!FLAG_print_break_location) return; | 2283 if (!FLAG_print_break_location) return; |
2286 HandleScope scope(isolate_); | 2284 HandleScope scope(isolate_); |
2287 JavaScriptFrameIterator iterator(isolate_); | 2285 JavaScriptFrameIterator iterator(isolate_); |
2288 if (iterator.done()) return; | 2286 if (iterator.done()) return; |
2289 JavaScriptFrame* frame = iterator.frame(); | 2287 JavaScriptFrame* frame = iterator.frame(); |
2290 FrameSummary summary = FrameSummary::GetFirst(frame); | 2288 FrameSummary summary = FrameSummary::GetTop(frame); |
2291 int source_position = summary.SourcePosition(); | 2289 int source_position = summary.SourcePosition(); |
2292 Handle<Object> script_obj = summary.script(); | 2290 Handle<Object> script_obj = summary.script(); |
2293 PrintF("[debug] break in function '"); | 2291 PrintF("[debug] break in function '"); |
2294 summary.FunctionName()->PrintOn(stdout); | 2292 summary.FunctionName()->PrintOn(stdout); |
2295 PrintF("'.\n"); | 2293 PrintF("'.\n"); |
2296 if (script_obj->IsScript()) { | 2294 if (script_obj->IsScript()) { |
2297 Handle<Script> script = Handle<Script>::cast(script_obj); | 2295 Handle<Script> script = Handle<Script>::cast(script_obj); |
2298 Handle<String> source(String::cast(script->source())); | 2296 Handle<String> source(String::cast(script->source())); |
2299 Script::InitLineEnds(script); | 2297 Script::InitLineEnds(script); |
2300 int line = | 2298 int line = |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2645 logger_->DebugEvent("Put", message.text()); | 2643 logger_->DebugEvent("Put", message.text()); |
2646 } | 2644 } |
2647 | 2645 |
2648 void LockingCommandMessageQueue::Clear() { | 2646 void LockingCommandMessageQueue::Clear() { |
2649 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2647 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
2650 queue_.Clear(); | 2648 queue_.Clear(); |
2651 } | 2649 } |
2652 | 2650 |
2653 } // namespace internal | 2651 } // namespace internal |
2654 } // namespace v8 | 2652 } // namespace v8 |
OLD | NEW |