Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(342)

Side by Side Diff: runtime/vm/debugger.cc

Issue 149123003: Handle all debugger stepping with the isolate single step flag (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/debugger.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 isolate_id_(ILLEGAL_ISOLATE_ID), 826 isolate_id_(ILLEGAL_ISOLATE_ID),
827 initialized_(false), 827 initialized_(false),
828 next_id_(1), 828 next_id_(1),
829 src_breakpoints_(NULL), 829 src_breakpoints_(NULL),
830 code_breakpoints_(NULL), 830 code_breakpoints_(NULL),
831 resume_action_(kContinue), 831 resume_action_(kContinue),
832 ignore_breakpoints_(false), 832 ignore_breakpoints_(false),
833 pause_event_(NULL), 833 pause_event_(NULL),
834 obj_cache_(NULL), 834 obj_cache_(NULL),
835 stack_trace_(NULL), 835 stack_trace_(NULL),
836 stepping_fp_(0),
836 exc_pause_info_(kNoPauseOnExceptions) { 837 exc_pause_info_(kNoPauseOnExceptions) {
837 } 838 }
838 839
839 840
840 Debugger::~Debugger() { 841 Debugger::~Debugger() {
841 isolate_id_ = ILLEGAL_ISOLATE_ID; 842 isolate_id_ = ILLEGAL_ISOLATE_ID;
842 ASSERT(!IsPaused()); 843 ASSERT(!IsPaused());
843 ASSERT(src_breakpoints_ == NULL); 844 ASSERT(src_breakpoints_ == NULL);
844 ASSERT(code_breakpoints_ == NULL); 845 ASSERT(code_breakpoints_ == NULL);
845 ASSERT(stack_trace_ == NULL); 846 ASSERT(stack_trace_ == NULL);
(...skipping 22 matching lines...) Expand all
868 const Library& library, 869 const Library& library,
869 const String& fname) { 870 const String& fname) {
870 ASSERT(!library.IsNull()); 871 ASSERT(!library.IsNull());
871 const Object& object = Object::Handle(library.LookupObject(fname)); 872 const Object& object = Object::Handle(library.LookupObject(fname));
872 if (!object.IsNull() && object.IsFunction()) { 873 if (!object.IsNull() && object.IsFunction()) {
873 return Function::Cast(object).raw(); 874 return Function::Cast(object).raw();
874 } 875 }
875 return Function::null(); 876 return Function::null();
876 } 877 }
877 878
879
878 void Debugger::SetSingleStep() { 880 void Debugger::SetSingleStep() {
879 isolate_->set_single_step(true);
880 resume_action_ = kSingleStep; 881 resume_action_ = kSingleStep;
881 } 882 }
882 883
884
883 void Debugger::SetStepOver() { 885 void Debugger::SetStepOver() {
884 isolate_->set_single_step(false);
885 resume_action_ = kStepOver; 886 resume_action_ = kStepOver;
886 } 887 }
887 888
889
888 void Debugger::SetStepOut() { 890 void Debugger::SetStepOut() {
889 isolate_->set_single_step(false);
890 resume_action_ = kStepOut; 891 resume_action_ = kStepOut;
891 } 892 }
892 893
893 RawFunction* Debugger::ResolveFunction(const Library& library, 894 RawFunction* Debugger::ResolveFunction(const Library& library,
894 const String& class_name, 895 const String& class_name,
895 const String& function_name) { 896 const String& function_name) {
896 ASSERT(!library.IsNull()); 897 ASSERT(!library.IsNull());
897 ASSERT(!class_name.IsNull()); 898 ASSERT(!class_name.IsNull());
898 ASSERT(!function_name.IsNull()); 899 ASSERT(!function_name.IsNull());
899 if (class_name.Length() == 0) { 900 if (class_name.Length() == 0) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 if (function.HasOptimizedCode()) { 961 if (function.HasOptimizedCode()) {
961 function.SwitchToUnoptimizedCode(); 962 function.SwitchToUnoptimizedCode();
962 } 963 }
963 } 964 }
964 } 965 }
965 } 966 }
966 } 967 }
967 } 968 }
968 969
969 970
970 void Debugger::InstrumentForStepping(const Function& target_function) { 971 void Debugger::SetInternalBreakpoints(const Function& target_function) {
971 if (target_function.is_native()) { 972 if (target_function.is_native()) {
972 // Can't instrument native functions. 973 // Can't instrument native functions.
973 return; 974 return;
974 } 975 }
975 if (!target_function.HasCode()) { 976 if (!target_function.HasCode()) {
976 Compiler::CompileFunction(target_function); 977 Compiler::CompileFunction(target_function);
977 // If there were any errors, ignore them silently and return without 978 // If there were any errors, ignore them silently and return without
978 // adding breakpoints to target. 979 // adding breakpoints to target.
979 if (!target_function.HasCode()) { 980 if (!target_function.HasCode()) {
980 return; 981 return;
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
1558 } else { 1559 } else {
1559 cbpt->Disable(); 1560 cbpt->Disable();
1560 } 1561 }
1561 } 1562 }
1562 cbpt = cbpt->next(); 1563 cbpt = cbpt->next();
1563 } 1564 }
1564 } 1565 }
1565 1566
1566 1567
1567 void Debugger::OneTimeBreakAtEntry(const Function& target_function) { 1568 void Debugger::OneTimeBreakAtEntry(const Function& target_function) {
1568 InstrumentForStepping(target_function); 1569 SetInternalBreakpoints(target_function);
1569 if (target_function.HasImplicitClosureFunction()) { 1570 if (target_function.HasImplicitClosureFunction()) {
1570 const Function& closure_func = 1571 const Function& closure_func =
1571 Function::Handle(target_function.ImplicitClosureFunction()); 1572 Function::Handle(target_function.ImplicitClosureFunction());
1572 InstrumentForStepping(closure_func); 1573 SetInternalBreakpoints(closure_func);
1573 } 1574 }
1574 } 1575 }
1575 1576
1576 1577
1577 SourceBreakpoint* Debugger::SetBreakpointAtEntry( 1578 SourceBreakpoint* Debugger::SetBreakpointAtEntry(
1578 const Function& target_function) { 1579 const Function& target_function) {
1579 ASSERT(!target_function.IsNull()); 1580 ASSERT(!target_function.IsNull());
1580 const Script& script = Script::Handle(target_function.script()); 1581 const Script& script = Script::Handle(target_function.script());
1581 return SetBreakpoint(script, target_function.token_pos()); 1582 return SetBreakpoint(script, target_function.token_pos());
1582 } 1583 }
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 } 1879 }
1879 const Class& cls = Class::Handle(func.Owner()); 1880 const Class& cls = Class::Handle(func.Owner());
1880 const Library& lib = Library::Handle(cls.library()); 1881 const Library& lib = Library::Handle(cls.library());
1881 return lib.IsDebuggable(); 1882 return lib.IsDebuggable();
1882 } 1883 }
1883 1884
1884 1885
1885 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, 1886 void Debugger::SignalPausedEvent(ActivationFrame* top_frame,
1886 SourceBreakpoint* bpt) { 1887 SourceBreakpoint* bpt) {
1887 resume_action_ = kContinue; 1888 resume_action_ = kContinue;
1889 stepping_fp_ = 0;
1888 isolate_->set_single_step(false); 1890 isolate_->set_single_step(false);
1889 ASSERT(!IsPaused()); 1891 ASSERT(!IsPaused());
1890 ASSERT(obj_cache_ == NULL); 1892 ASSERT(obj_cache_ == NULL);
1891 DebuggerEvent event(kBreakpointReached); 1893 DebuggerEvent event(kBreakpointReached);
1892 event.top_frame = top_frame; 1894 event.top_frame = top_frame;
1893 event.breakpoint = bpt; 1895 event.breakpoint = bpt;
1894 Pause(&event); 1896 Pause(&event);
1895 } 1897 }
1896 1898
1897 1899
1898 void Debugger::SingleStepCallback() { 1900 static uword DebuggableCallerFP(DebuggerStackTrace* stack_trace) {
1899 ASSERT(resume_action_ == kSingleStep); 1901 for (intptr_t i = 1; i < stack_trace->Length(); i++) {
1902 ActivationFrame* frame = stack_trace->FrameAt(i);
1903 if (frame->IsDebuggable()) {
1904 return frame->fp();
1905 }
1906 }
1907 return 0;
1908 }
1909
1910
1911 void Debugger::DebuggerStepCallback() {
1900 ASSERT(isolate_->single_step()); 1912 ASSERT(isolate_->single_step());
1901 // We can't get here unless the debugger event handler enabled 1913 // We can't get here unless the debugger event handler enabled
1902 // single stepping. 1914 // single stepping.
1903 ASSERT(event_handler_ != NULL); 1915 ASSERT(event_handler_ != NULL);
1904 // Don't pause recursively. 1916 // Don't pause recursively.
1905 if (IsPaused()) return; 1917 if (IsPaused()) return;
1906 1918
1907 // Check whether we are in a Dart function that the user is 1919 // Check whether we are in a Dart function that the user is
1908 // interested in. 1920 // interested in. If we saved the frame pointer of a stack frame
1921 // the user is interested in, we ignore the single step if we are
1922 // in a callee of that frame. Note that we assume that the stack
1923 // grows towards lower addresses.
1909 ActivationFrame* frame = TopDartFrame(); 1924 ActivationFrame* frame = TopDartFrame();
1910 ASSERT(frame != NULL); 1925 ASSERT(frame != NULL);
1911 const Function& func = frame->function(); 1926 if ((stepping_fp_ != 0) && (stepping_fp_ > frame->fp())) {
1912 if (!IsDebuggable(func)) { 1927 return;
1928 }
1929 // If an "interesting" frame is set, we are either in that frame
1930 // or the program has returned from that frame. Let the user set
1931 // the "interesting" frame again next time we pause.
1932 stepping_fp_ = 0;
1933
1934 if (!frame->IsDebuggable()) {
1913 return; 1935 return;
1914 } 1936 }
1915 if (frame->TokenPos() == Scanner::kNoSourcePos) { 1937 if (frame->TokenPos() == Scanner::kNoSourcePos) {
1916 return; 1938 return;
1917 } 1939 }
1940
1918 // Don't pause for a single step if there is a breakpoint set 1941 // Don't pause for a single step if there is a breakpoint set
1919 // at this location. 1942 // at this location.
1920 if (HasActiveBreakpoint(frame->pc())) { 1943 if (HasActiveBreakpoint(frame->pc())) {
1921 return; 1944 return;
1922 } 1945 }
1923 1946
1924 if (FLAG_verbose_debug) { 1947 if (FLAG_verbose_debug) {
1925 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n", 1948 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n",
1926 String::Handle(frame->SourceUrl()).ToCString(), 1949 String::Handle(frame->SourceUrl()).ToCString(),
1927 frame->LineNumber(), 1950 frame->LineNumber(),
1928 String::Handle(frame->QualifiedFunctionName()).ToCString(), 1951 String::Handle(frame->QualifiedFunctionName()).ToCString(),
1929 frame->TokenPos()); 1952 frame->TokenPos());
1930 } 1953 }
1931 1954
1932 ASSERT(stack_trace_ == NULL); 1955 ASSERT(stack_trace_ == NULL);
1933 stack_trace_ = CollectStackTrace(); 1956 stack_trace_ = CollectStackTrace();
1934 SignalPausedEvent(frame, NULL); 1957 SignalPausedEvent(frame, NULL);
1935 1958
1936 RemoveInternalBreakpoints(); 1959 if (resume_action_ == kSingleStep) {
1937 if (resume_action_ == kStepOver) { 1960 isolate_->set_single_step(true);
1938 InstrumentForStepping(func); 1961 stepping_fp_ = 0;
1962 } else if (resume_action_ == kStepOver) {
1963 isolate_->set_single_step(true);
1964 stepping_fp_ = frame->fp();
1939 } else if (resume_action_ == kStepOut) { 1965 } else if (resume_action_ == kStepOut) {
1940 if (stack_trace_->Length() > 1) { 1966 isolate_->set_single_step(true);
1941 ActivationFrame* caller_frame = stack_trace_->FrameAt(1); 1967 stepping_fp_ = DebuggableCallerFP(stack_trace_);
1942 InstrumentForStepping(caller_frame->function());
1943 }
1944 } 1968 }
1945 stack_trace_ = NULL; 1969 stack_trace_ = NULL;
1946 } 1970 }
1947 1971
1948 1972
1949 void Debugger::SignalBpReached() { 1973 void Debugger::SignalBpReached() {
1950 // We ignore this breakpoint when the VM is executing code invoked 1974 // We ignore this breakpoint when the VM is executing code invoked
1951 // by the debugger to evaluate variables values, or when we see a nested 1975 // by the debugger to evaluate variables values, or when we see a nested
1952 // breakpoint or exception event. 1976 // breakpoint or exception event.
1953 if (ignore_breakpoints_ || IsPaused()) { 1977 if (ignore_breakpoints_ || IsPaused() || (event_handler_ == NULL)) {
1954 return; 1978 return;
1955 } 1979 }
1956 DebuggerStackTrace* stack_trace = CollectStackTrace(); 1980 DebuggerStackTrace* stack_trace = CollectStackTrace();
1957 ASSERT(stack_trace->Length() > 0); 1981 ASSERT(stack_trace->Length() > 0);
1958 ActivationFrame* top_frame = stack_trace->FrameAt(0); 1982 ActivationFrame* top_frame = stack_trace->FrameAt(0);
1959 ASSERT(top_frame != NULL); 1983 ASSERT(top_frame != NULL);
1960 CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc()); 1984 CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc());
1961 ASSERT(bpt != NULL); 1985 ASSERT(bpt != NULL);
1962 1986
1963 bool report_bp = true;
1964 if (bpt->IsInternal() && !IsDebuggable(top_frame->function())) {
1965 report_bp = false;
1966 }
1967 if (FLAG_verbose_debug) { 1987 if (FLAG_verbose_debug) {
1968 OS::Print(">>> %s %s breakpoint at %s:%" Pd " " 1988 OS::Print(">>> hit %s breakpoint at %s:%" Pd " "
1969 "(token %" Pd ") (address %#" Px ")\n", 1989 "(token %" Pd ") (address %#" Px ")\n",
1970 report_bp ? "hit" : "ignore",
1971 bpt->IsInternal() ? "internal" : "user", 1990 bpt->IsInternal() ? "internal" : "user",
1972 String::Handle(bpt->SourceUrl()).ToCString(), 1991 String::Handle(bpt->SourceUrl()).ToCString(),
1973 bpt->LineNumber(), 1992 bpt->LineNumber(),
1974 bpt->token_pos(), 1993 bpt->token_pos(),
1975 top_frame->pc()); 1994 top_frame->pc());
1976 } 1995 }
1977 1996
1978 if (report_bp && (event_handler_ != NULL)) { 1997 ASSERT(stack_trace_ == NULL);
1979 ASSERT(stack_trace_ == NULL); 1998 stack_trace_ = stack_trace;
1980 stack_trace_ = stack_trace; 1999 SignalPausedEvent(top_frame, bpt->src_bpt_);
1981 SignalPausedEvent(top_frame, bpt->src_bpt_); 2000 stack_trace_ = NULL;
1982 stack_trace_ = NULL; 2001
2002 if (resume_action_ == kSingleStep) {
2003 isolate_->set_single_step(true);
2004 stepping_fp_ = 0;
2005 } else if (resume_action_ == kStepOver) {
2006 isolate_->set_single_step(true);
2007 stepping_fp_ = top_frame->fp();
2008 } else if (resume_action_ == kStepOut) {
2009 isolate_->set_single_step(true);
2010 stepping_fp_ = DebuggableCallerFP(stack_trace);
1983 } 2011 }
1984 2012 if (bpt->IsInternal()) {
1985 Function& func_to_instrument = Function::Handle(); 2013 RemoveInternalBreakpoints();
1986 if ((resume_action_ == kStepOver) &&
1987 (bpt->breakpoint_kind_ == PcDescriptors::kReturn)) {
1988 resume_action_ = kStepOut;
1989 }
1990 if (resume_action_ == kStepOver) {
1991 ASSERT(bpt->breakpoint_kind_ != PcDescriptors::kReturn);
1992 func_to_instrument = bpt->function();
1993 } else if (resume_action_ == kStepOut) {
1994 if (stack_trace->Length() > 1) {
1995 ActivationFrame* caller_frame = stack_trace->FrameAt(1);
1996 func_to_instrument = caller_frame->function().raw();
1997 }
1998 } else {
1999 ASSERT((resume_action_ == kContinue) || (resume_action_ == kSingleStep));
2000 // Nothing to do here. Any potential instrumentation will be removed
2001 // below. Single stepping is handled by the single step callback.
2002 }
2003
2004 if (func_to_instrument.IsNull() ||
2005 (func_to_instrument.raw() != bpt->function())) {
2006 RemoveInternalBreakpoints(); // *bpt is now invalid.
2007 }
2008 if (!func_to_instrument.IsNull()) {
2009 InstrumentForStepping(func_to_instrument);
2010 } 2014 }
2011 } 2015 }
2012 2016
2013 2017
2014 void Debugger::Initialize(Isolate* isolate) { 2018 void Debugger::Initialize(Isolate* isolate) {
2015 if (initialized_) { 2019 if (initialized_) {
2016 return; 2020 return;
2017 } 2021 }
2018 isolate_ = isolate; 2022 isolate_ = isolate;
2019 // Use the isolate's control port as the isolate_id for debugging. 2023 // Use the isolate's control port as the isolate_id for debugging.
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
2258 } 2262 }
2259 2263
2260 2264
2261 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 2265 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
2262 ASSERT(bpt->next() == NULL); 2266 ASSERT(bpt->next() == NULL);
2263 bpt->set_next(code_breakpoints_); 2267 bpt->set_next(code_breakpoints_);
2264 code_breakpoints_ = bpt; 2268 code_breakpoints_ = bpt;
2265 } 2269 }
2266 2270
2267 } // namespace dart 2271 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698