| 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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 deopt_frame_offset_(deopt_frame_offset), | 180 deopt_frame_offset_(deopt_frame_offset), |
| 181 vars_initialized_(false), | 181 vars_initialized_(false), |
| 182 var_descriptors_(LocalVarDescriptors::ZoneHandle()), | 182 var_descriptors_(LocalVarDescriptors::ZoneHandle()), |
| 183 desc_indices_(8), | 183 desc_indices_(8), |
| 184 pc_desc_(PcDescriptors::ZoneHandle()) { | 184 pc_desc_(PcDescriptors::ZoneHandle()) { |
| 185 } | 185 } |
| 186 | 186 |
| 187 | 187 |
| 188 void Debugger::SignalIsolateEvent(EventType type) { | 188 void Debugger::SignalIsolateEvent(EventType type) { |
| 189 if (event_handler_ != NULL) { | 189 if (event_handler_ != NULL) { |
| 190 Debugger* debugger = Isolate::Current()->debugger(); | |
| 191 ASSERT(debugger != NULL); | |
| 192 DebuggerEvent event(type); | 190 DebuggerEvent event(type); |
| 193 event.isolate_id = debugger->GetIsolateId(); | 191 event.isolate_id = isolate_id_; |
| 194 ASSERT(event.isolate_id != ILLEGAL_ISOLATE_ID); | 192 ASSERT(event.isolate_id != ILLEGAL_ISOLATE_ID); |
| 195 if (type == kIsolateInterrupted) { | 193 if (type == kIsolateInterrupted) { |
| 196 DebuggerStackTrace* stack_trace = debugger->CollectStackTrace(); | 194 DebuggerStackTrace* trace = CollectStackTrace(); |
| 197 ASSERT(stack_trace->Length() > 0); | 195 ASSERT(trace->Length() > 0); |
| 198 ASSERT(debugger->stack_trace_ == NULL); | 196 ASSERT(stack_trace_ == NULL); |
| 199 debugger->stack_trace_ = stack_trace; | 197 stack_trace_ = trace; |
| 200 debugger->Pause(&event); | 198 resume_action_ = kContinue; |
| 201 debugger->stack_trace_ = NULL; | 199 Pause(&event); |
| 202 // TODO(asiva): Need some work here to be able to single step after | 200 HandleSteppingRequest(trace); |
| 203 // an interrupt. | 201 stack_trace_ = NULL; |
| 204 } else { | 202 } else { |
| 205 (*event_handler_)(&event); | 203 (*event_handler_)(&event); |
| 206 } | 204 } |
| 207 } | 205 } |
| 208 } | 206 } |
| 209 | 207 |
| 210 | 208 |
| 209 void Debugger::SignalIsolateInterrupted() { |
| 210 if (event_handler_ != NULL) { |
| 211 Debugger* debugger = Isolate::Current()->debugger(); |
| 212 ASSERT(debugger != NULL); |
| 213 debugger->SignalIsolateEvent(kIsolateInterrupted); |
| 214 } |
| 215 } |
| 216 |
| 217 |
| 211 const char* Debugger::QualifiedFunctionName(const Function& func) { | 218 const char* Debugger::QualifiedFunctionName(const Function& func) { |
| 212 const String& func_name = String::Handle(func.name()); | 219 const String& func_name = String::Handle(func.name()); |
| 213 Class& func_class = Class::Handle(func.Owner()); | 220 Class& func_class = Class::Handle(func.Owner()); |
| 214 String& class_name = String::Handle(func_class.Name()); | 221 String& class_name = String::Handle(func_class.Name()); |
| 215 | 222 |
| 216 const char* kFormat = "%s%s%s"; | 223 const char* kFormat = "%s%s%s"; |
| 217 intptr_t len = OS::SNPrint(NULL, 0, kFormat, | 224 intptr_t len = OS::SNPrint(NULL, 0, kFormat, |
| 218 func_class.IsTopLevel() ? "" : class_name.ToCString(), | 225 func_class.IsTopLevel() ? "" : class_name.ToCString(), |
| 219 func_class.IsTopLevel() ? "" : ".", | 226 func_class.IsTopLevel() ? "" : ".", |
| 220 func_name.ToCString()); | 227 func_name.ToCString()); |
| (...skipping 1698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1919 pause_event_ = event; | 1926 pause_event_ = event; |
| 1920 obj_cache_ = new RemoteObjectCache(64); | 1927 obj_cache_ = new RemoteObjectCache(64); |
| 1921 | 1928 |
| 1922 (*event_handler_)(event); | 1929 (*event_handler_)(event); |
| 1923 | 1930 |
| 1924 pause_event_ = NULL; | 1931 pause_event_ = NULL; |
| 1925 obj_cache_ = NULL; // Zone allocated | 1932 obj_cache_ = NULL; // Zone allocated |
| 1926 } | 1933 } |
| 1927 | 1934 |
| 1928 | 1935 |
| 1936 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace) { |
| 1937 stepping_fp_ = 0; |
| 1938 if (resume_action_ == kSingleStep) { |
| 1939 isolate_->set_single_step(true); |
| 1940 } else if (resume_action_ == kStepOver) { |
| 1941 isolate_->set_single_step(true); |
| 1942 ASSERT(stack_trace->Length() > 0); |
| 1943 stepping_fp_ = stack_trace->FrameAt(0)->fp(); |
| 1944 } else if (resume_action_ == kStepOut) { |
| 1945 isolate_->set_single_step(true); |
| 1946 // Find topmost caller that is debuggable. |
| 1947 for (intptr_t i = 1; i < stack_trace->Length(); i++) { |
| 1948 ActivationFrame* frame = stack_trace->FrameAt(i); |
| 1949 if (frame->IsDebuggable()) { |
| 1950 stepping_fp_ = frame->fp(); |
| 1951 break; |
| 1952 } |
| 1953 } |
| 1954 } |
| 1955 } |
| 1956 |
| 1957 |
| 1929 bool Debugger::IsDebuggable(const Function& func) { | 1958 bool Debugger::IsDebuggable(const Function& func) { |
| 1930 if (!IsDebuggableFunctionKind(func)) { | 1959 if (!IsDebuggableFunctionKind(func)) { |
| 1931 return false; | 1960 return false; |
| 1932 } | 1961 } |
| 1933 const Class& cls = Class::Handle(func.Owner()); | 1962 const Class& cls = Class::Handle(func.Owner()); |
| 1934 const Library& lib = Library::Handle(cls.library()); | 1963 const Library& lib = Library::Handle(cls.library()); |
| 1935 return lib.IsDebuggable(); | 1964 return lib.IsDebuggable(); |
| 1936 } | 1965 } |
| 1937 | 1966 |
| 1938 | 1967 |
| 1939 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, | 1968 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, |
| 1940 SourceBreakpoint* bpt) { | 1969 SourceBreakpoint* bpt) { |
| 1941 resume_action_ = kContinue; | 1970 resume_action_ = kContinue; |
| 1942 stepping_fp_ = 0; | 1971 stepping_fp_ = 0; |
| 1943 isolate_->set_single_step(false); | 1972 isolate_->set_single_step(false); |
| 1944 ASSERT(!IsPaused()); | 1973 ASSERT(!IsPaused()); |
| 1945 ASSERT(obj_cache_ == NULL); | 1974 ASSERT(obj_cache_ == NULL); |
| 1946 DebuggerEvent event(kBreakpointReached); | 1975 DebuggerEvent event(kBreakpointReached); |
| 1947 event.top_frame = top_frame; | 1976 event.top_frame = top_frame; |
| 1948 event.breakpoint = bpt; | 1977 event.breakpoint = bpt; |
| 1949 Pause(&event); | 1978 Pause(&event); |
| 1950 } | 1979 } |
| 1951 | 1980 |
| 1952 | 1981 |
| 1953 static uword DebuggableCallerFP(DebuggerStackTrace* stack_trace) { | |
| 1954 for (intptr_t i = 1; i < stack_trace->Length(); i++) { | |
| 1955 ActivationFrame* frame = stack_trace->FrameAt(i); | |
| 1956 if (frame->IsDebuggable()) { | |
| 1957 return frame->fp(); | |
| 1958 } | |
| 1959 } | |
| 1960 return 0; | |
| 1961 } | |
| 1962 | |
| 1963 | |
| 1964 void Debugger::DebuggerStepCallback() { | 1982 void Debugger::DebuggerStepCallback() { |
| 1965 ASSERT(isolate_->single_step()); | 1983 ASSERT(isolate_->single_step()); |
| 1966 // We can't get here unless the debugger event handler enabled | 1984 // We can't get here unless the debugger event handler enabled |
| 1967 // single stepping. | 1985 // single stepping. |
| 1968 ASSERT(event_handler_ != NULL); | 1986 ASSERT(event_handler_ != NULL); |
| 1969 // Don't pause recursively. | 1987 // Don't pause recursively. |
| 1970 if (IsPaused()) return; | 1988 if (IsPaused()) return; |
| 1971 | 1989 |
| 1972 // Check whether we are in a Dart function that the user is | 1990 // Check whether we are in a Dart function that the user is |
| 1973 // interested in. If we saved the frame pointer of a stack frame | 1991 // interested in. If we saved the frame pointer of a stack frame |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2001 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n", | 2019 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n", |
| 2002 String::Handle(frame->SourceUrl()).ToCString(), | 2020 String::Handle(frame->SourceUrl()).ToCString(), |
| 2003 frame->LineNumber(), | 2021 frame->LineNumber(), |
| 2004 String::Handle(frame->QualifiedFunctionName()).ToCString(), | 2022 String::Handle(frame->QualifiedFunctionName()).ToCString(), |
| 2005 frame->TokenPos()); | 2023 frame->TokenPos()); |
| 2006 } | 2024 } |
| 2007 | 2025 |
| 2008 ASSERT(stack_trace_ == NULL); | 2026 ASSERT(stack_trace_ == NULL); |
| 2009 stack_trace_ = CollectStackTrace(); | 2027 stack_trace_ = CollectStackTrace(); |
| 2010 SignalPausedEvent(frame, NULL); | 2028 SignalPausedEvent(frame, NULL); |
| 2011 | 2029 HandleSteppingRequest(stack_trace_); |
| 2012 if (resume_action_ == kSingleStep) { | |
| 2013 isolate_->set_single_step(true); | |
| 2014 stepping_fp_ = 0; | |
| 2015 } else if (resume_action_ == kStepOver) { | |
| 2016 isolate_->set_single_step(true); | |
| 2017 stepping_fp_ = frame->fp(); | |
| 2018 } else if (resume_action_ == kStepOut) { | |
| 2019 isolate_->set_single_step(true); | |
| 2020 stepping_fp_ = DebuggableCallerFP(stack_trace_); | |
| 2021 } | |
| 2022 stack_trace_ = NULL; | 2030 stack_trace_ = NULL; |
| 2023 } | 2031 } |
| 2024 | 2032 |
| 2025 | 2033 |
| 2026 void Debugger::SignalBpReached() { | 2034 void Debugger::SignalBpReached() { |
| 2027 // We ignore this breakpoint when the VM is executing code invoked | 2035 // We ignore this breakpoint when the VM is executing code invoked |
| 2028 // by the debugger to evaluate variables values, or when we see a nested | 2036 // by the debugger to evaluate variables values, or when we see a nested |
| 2029 // breakpoint or exception event. | 2037 // breakpoint or exception event. |
| 2030 if (ignore_breakpoints_ || IsPaused() || (event_handler_ == NULL)) { | 2038 if (ignore_breakpoints_ || IsPaused() || (event_handler_ == NULL)) { |
| 2031 return; | 2039 return; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2043 bpt->IsInternal() ? "internal" : "user", | 2051 bpt->IsInternal() ? "internal" : "user", |
| 2044 String::Handle(bpt->SourceUrl()).ToCString(), | 2052 String::Handle(bpt->SourceUrl()).ToCString(), |
| 2045 bpt->LineNumber(), | 2053 bpt->LineNumber(), |
| 2046 bpt->token_pos(), | 2054 bpt->token_pos(), |
| 2047 top_frame->pc()); | 2055 top_frame->pc()); |
| 2048 } | 2056 } |
| 2049 | 2057 |
| 2050 ASSERT(stack_trace_ == NULL); | 2058 ASSERT(stack_trace_ == NULL); |
| 2051 stack_trace_ = stack_trace; | 2059 stack_trace_ = stack_trace; |
| 2052 SignalPausedEvent(top_frame, bpt->src_bpt_); | 2060 SignalPausedEvent(top_frame, bpt->src_bpt_); |
| 2061 HandleSteppingRequest(stack_trace_); |
| 2053 stack_trace_ = NULL; | 2062 stack_trace_ = NULL; |
| 2054 | |
| 2055 if (resume_action_ == kSingleStep) { | |
| 2056 isolate_->set_single_step(true); | |
| 2057 stepping_fp_ = 0; | |
| 2058 } else if (resume_action_ == kStepOver) { | |
| 2059 isolate_->set_single_step(true); | |
| 2060 stepping_fp_ = top_frame->fp(); | |
| 2061 } else if (resume_action_ == kStepOut) { | |
| 2062 isolate_->set_single_step(true); | |
| 2063 stepping_fp_ = DebuggableCallerFP(stack_trace); | |
| 2064 } | |
| 2065 if (bpt->IsInternal()) { | 2063 if (bpt->IsInternal()) { |
| 2066 RemoveInternalBreakpoints(); | 2064 RemoveInternalBreakpoints(); |
| 2067 } | 2065 } |
| 2068 } | 2066 } |
| 2069 | 2067 |
| 2070 | 2068 |
| 2071 void Debugger::Initialize(Isolate* isolate) { | 2069 void Debugger::Initialize(Isolate* isolate) { |
| 2072 if (initialized_) { | 2070 if (initialized_) { |
| 2073 return; | 2071 return; |
| 2074 } | 2072 } |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2315 } | 2313 } |
| 2316 | 2314 |
| 2317 | 2315 |
| 2318 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2316 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 2319 ASSERT(bpt->next() == NULL); | 2317 ASSERT(bpt->next() == NULL); |
| 2320 bpt->set_next(code_breakpoints_); | 2318 bpt->set_next(code_breakpoints_); |
| 2321 code_breakpoints_ = bpt; | 2319 code_breakpoints_ = bpt; |
| 2322 } | 2320 } |
| 2323 | 2321 |
| 2324 } // namespace dart | 2322 } // namespace dart |
| OLD | NEW |