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

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

Issue 118603002: Keep track of current "pause" event in the debugger. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years 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') | runtime/vm/debugger_test.cc » ('j') | 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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 void Debugger::SignalIsolateEvent(EventType type) { 181 void Debugger::SignalIsolateEvent(EventType type) {
182 if (event_handler_ != NULL) { 182 if (event_handler_ != NULL) {
183 Debugger* debugger = Isolate::Current()->debugger(); 183 Debugger* debugger = Isolate::Current()->debugger();
184 ASSERT(debugger != NULL); 184 ASSERT(debugger != NULL);
185 DebuggerEvent event(type); 185 DebuggerEvent event(type);
186 event.isolate_id = debugger->GetIsolateId(); 186 event.isolate_id = debugger->GetIsolateId();
187 ASSERT(event.isolate_id != ILLEGAL_ISOLATE_ID); 187 ASSERT(event.isolate_id != ILLEGAL_ISOLATE_ID);
188 if (type == kIsolateInterrupted) { 188 if (type == kIsolateInterrupted) {
189 DebuggerStackTrace* stack_trace = debugger->CollectStackTrace(); 189 DebuggerStackTrace* stack_trace = debugger->CollectStackTrace();
190 ASSERT(stack_trace->Length() > 0); 190 ASSERT(stack_trace->Length() > 0);
191 ASSERT(debugger->stack_trace_ == NULL); 191 ASSERT(debugger->stack_trace_ == NULL);
turnidge 2013/12/18 21:27:58 in_event_handler_ was missing here before. I thin
192 ASSERT(debugger->obj_cache_ == NULL);
193 debugger->obj_cache_ = new RemoteObjectCache(64);
194 debugger->stack_trace_ = stack_trace; 192 debugger->stack_trace_ = stack_trace;
195 (*event_handler_)(&event); 193 debugger->Pause(&event);
196 debugger->stack_trace_ = NULL; 194 debugger->stack_trace_ = NULL;
197 debugger->obj_cache_ = NULL; // Remote object cache is zone allocated.
198 // TODO(asiva): Need some work here to be able to single step after 195 // TODO(asiva): Need some work here to be able to single step after
199 // an interrupt. 196 // an interrupt.
200 } else { 197 } else {
201 (*event_handler_)(&event); 198 (*event_handler_)(&event);
202 } 199 }
203 } 200 }
204 } 201 }
205 202
206 203
207 const char* Debugger::QualifiedFunctionName(const Function& func) { 204 const char* Debugger::QualifiedFunctionName(const Function& func) {
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 ASSERT(IsValidId(obj_id)); 845 ASSERT(IsValidId(obj_id));
849 return objs_->At(obj_id); 846 return objs_->At(obj_id);
850 } 847 }
851 848
852 849
853 Debugger::Debugger() 850 Debugger::Debugger()
854 : isolate_(NULL), 851 : isolate_(NULL),
855 isolate_id_(ILLEGAL_ISOLATE_ID), 852 isolate_id_(ILLEGAL_ISOLATE_ID),
856 initialized_(false), 853 initialized_(false),
857 next_id_(1), 854 next_id_(1),
858 stack_trace_(NULL),
859 obj_cache_(NULL),
860 src_breakpoints_(NULL), 855 src_breakpoints_(NULL),
861 code_breakpoints_(NULL), 856 code_breakpoints_(NULL),
862 resume_action_(kContinue), 857 resume_action_(kContinue),
863 ignore_breakpoints_(false), 858 ignore_breakpoints_(false),
864 in_event_notification_(false), 859 pause_event_(NULL),
860 obj_cache_(NULL),
861 stack_trace_(NULL),
865 exc_pause_info_(kNoPauseOnExceptions) { 862 exc_pause_info_(kNoPauseOnExceptions) {
866 } 863 }
867 864
868 865
869 Debugger::~Debugger() { 866 Debugger::~Debugger() {
870 isolate_id_ = ILLEGAL_ISOLATE_ID; 867 isolate_id_ = ILLEGAL_ISOLATE_ID;
871 ASSERT(!in_event_notification_); 868 ASSERT(!IsPaused());
872 ASSERT(src_breakpoints_ == NULL); 869 ASSERT(src_breakpoints_ == NULL);
873 ASSERT(code_breakpoints_ == NULL); 870 ASSERT(code_breakpoints_ == NULL);
874 ASSERT(stack_trace_ == NULL); 871 ASSERT(stack_trace_ == NULL);
875 ASSERT(obj_cache_ == NULL); 872 ASSERT(obj_cache_ == NULL);
876 } 873 }
877 874
878 875
879 void Debugger::Shutdown() { 876 void Debugger::Shutdown() {
880 while (src_breakpoints_ != NULL) { 877 while (src_breakpoints_ != NULL) {
881 SourceBreakpoint* bpt = src_breakpoints_; 878 SourceBreakpoint* bpt = src_breakpoints_;
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 return false; 1260 return false;
1264 } 1261 }
1265 1262
1266 1263
1267 void Debugger::SignalExceptionThrown(const Instance& exc) { 1264 void Debugger::SignalExceptionThrown(const Instance& exc) {
1268 // We ignore this exception event when the VM is executing code invoked 1265 // We ignore this exception event when the VM is executing code invoked
1269 // by the debugger to evaluate variables values, when we see a nested 1266 // by the debugger to evaluate variables values, when we see a nested
1270 // breakpoint or exception event, or if the debugger is not 1267 // breakpoint or exception event, or if the debugger is not
1271 // interested in exception events. 1268 // interested in exception events.
1272 if (ignore_breakpoints_ || 1269 if (ignore_breakpoints_ ||
1273 in_event_notification_ || 1270 IsPaused() ||
1274 (event_handler_ == NULL) || 1271 (event_handler_ == NULL) ||
1275 (exc_pause_info_ == kNoPauseOnExceptions)) { 1272 (exc_pause_info_ == kNoPauseOnExceptions)) {
1276 return; 1273 return;
1277 } 1274 }
1278 DebuggerStackTrace* stack_trace = CollectStackTrace(); 1275 DebuggerStackTrace* stack_trace = CollectStackTrace();
1279 if (!ShouldPauseOnException(stack_trace, exc)) { 1276 if (!ShouldPauseOnException(stack_trace, exc)) {
1280 return; 1277 return;
1281 } 1278 }
1279 DebuggerEvent event(kExceptionThrown);
1280 event.exception = &exc;
1282 ASSERT(stack_trace_ == NULL); 1281 ASSERT(stack_trace_ == NULL);
1283 stack_trace_ = stack_trace; 1282 stack_trace_ = stack_trace;
1284 ASSERT(obj_cache_ == NULL); 1283 Pause(&event);
1285 in_event_notification_ = true;
1286 obj_cache_ = new RemoteObjectCache(64);
1287 DebuggerEvent event(kExceptionThrown);
1288 event.exception = &exc;
1289 (*event_handler_)(&event);
1290 in_event_notification_ = false;
1291 stack_trace_ = NULL; 1284 stack_trace_ = NULL;
1292 obj_cache_ = NULL; // Remote object cache is zone allocated.
1293 } 1285 }
1294 1286
1295 1287
1296 // Given a function and a token position range, return the best fit 1288 // Given a function and a token position range, return the best fit
1297 // token position to set a breakpoint. 1289 // token position to set a breakpoint.
1298 // If multiple possible breakpoint positions are within the given range, 1290 // If multiple possible breakpoint positions are within the given range,
1299 // the one with the lowest machine code address is picked. 1291 // the one with the lowest machine code address is picked.
1300 // If no possible breakpoint location exists in the given range, the closest 1292 // If no possible breakpoint location exists in the given range, the closest
1301 // token position after the range is returned. 1293 // token position after the range is returned.
1302 intptr_t Debugger::ResolveBreakpointPos(const Function& func, 1294 intptr_t Debugger::ResolveBreakpointPos(const Function& func,
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 cbpt = cbpt->next(); 1744 cbpt = cbpt->next();
1753 } 1745 }
1754 } 1746 }
1755 1747
1756 1748
1757 void Debugger::SetEventHandler(EventHandler* handler) { 1749 void Debugger::SetEventHandler(EventHandler* handler) {
1758 event_handler_ = handler; 1750 event_handler_ = handler;
1759 } 1751 }
1760 1752
1761 1753
1754 void Debugger::Pause(DebuggerEvent* event) {
1755 ASSERT(!IsPaused()); // No recursive pausing.
1756 ASSERT(obj_cache_ == NULL);
1757
1758 pause_event_ = event;
1759 obj_cache_ = new RemoteObjectCache(64);
1760
1761 (*event_handler_)(event);
1762
1763 pause_event_ = NULL;
1764 obj_cache_ = NULL; // Zone allocated
1765 }
1766
1767
1762 bool Debugger::IsDebuggable(const Function& func) { 1768 bool Debugger::IsDebuggable(const Function& func) {
1763 RawFunction::Kind fkind = func.kind(); 1769 RawFunction::Kind fkind = func.kind();
1764 if ((fkind == RawFunction::kImplicitGetter) || 1770 if ((fkind == RawFunction::kImplicitGetter) ||
1765 (fkind == RawFunction::kImplicitSetter) || 1771 (fkind == RawFunction::kImplicitSetter) ||
1766 (fkind == RawFunction::kImplicitStaticFinalGetter) || 1772 (fkind == RawFunction::kImplicitStaticFinalGetter) ||
1767 (fkind == RawFunction::kStaticInitializer) || 1773 (fkind == RawFunction::kStaticInitializer) ||
1768 (fkind == RawFunction::kMethodExtractor) || 1774 (fkind == RawFunction::kMethodExtractor) ||
1769 (fkind == RawFunction::kNoSuchMethodDispatcher) || 1775 (fkind == RawFunction::kNoSuchMethodDispatcher) ||
1770 (fkind == RawFunction::kInvokeFieldDispatcher)) { 1776 (fkind == RawFunction::kInvokeFieldDispatcher)) {
1771 return false; 1777 return false;
1772 } 1778 }
1773 const Class& cls = Class::Handle(func.Owner()); 1779 const Class& cls = Class::Handle(func.Owner());
1774 const Library& lib = Library::Handle(cls.library()); 1780 const Library& lib = Library::Handle(cls.library());
1775 return lib.IsDebuggable(); 1781 return lib.IsDebuggable();
1776 } 1782 }
1777 1783
1778 1784
1779 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, 1785 void Debugger::SignalPausedEvent(ActivationFrame* top_frame,
1780 SourceBreakpoint* bpt) { 1786 SourceBreakpoint* bpt) {
1781 resume_action_ = kContinue; 1787 resume_action_ = kContinue;
1782 isolate_->set_single_step(false); 1788 isolate_->set_single_step(false);
1783 ASSERT(!in_event_notification_); 1789 ASSERT(!IsPaused());
1784 ASSERT(obj_cache_ == NULL); 1790 ASSERT(obj_cache_ == NULL);
1785 in_event_notification_ = true;
1786 obj_cache_ = new RemoteObjectCache(64);
1787 DebuggerEvent event(kBreakpointReached); 1791 DebuggerEvent event(kBreakpointReached);
1788 event.top_frame = top_frame; 1792 event.top_frame = top_frame;
1789 event.breakpoint = bpt; 1793 event.breakpoint = bpt;
1790 (*event_handler_)(&event); 1794 Pause(&event);
1791 in_event_notification_ = false;
1792 obj_cache_ = NULL; // Remote object cache is zone allocated.
1793 } 1795 }
1794 1796
1795 1797
1796 void Debugger::SingleStepCallback() { 1798 void Debugger::SingleStepCallback() {
1797 ASSERT(resume_action_ == kSingleStep); 1799 ASSERT(resume_action_ == kSingleStep);
1798 ASSERT(isolate_->single_step()); 1800 ASSERT(isolate_->single_step());
1799 // We can't get here unless the debugger event handler enabled 1801 // We can't get here unless the debugger event handler enabled
1800 // single stepping. 1802 // single stepping.
1801 ASSERT(event_handler_ != NULL); 1803 ASSERT(event_handler_ != NULL);
1802 // Don't pause recursively. 1804 // Don't pause recursively.
1803 if (in_event_notification_) return; 1805 if (IsPaused()) return;
1804 1806
1805 // Check whether we are in a Dart function that the user is 1807 // Check whether we are in a Dart function that the user is
1806 // interested in. 1808 // interested in.
1807 ActivationFrame* frame = TopDartFrame(); 1809 ActivationFrame* frame = TopDartFrame();
1808 ASSERT(frame != NULL); 1810 ASSERT(frame != NULL);
1809 const Function& func = frame->function(); 1811 const Function& func = frame->function();
1810 if (!IsDebuggable(func)) { 1812 if (!IsDebuggable(func)) {
1811 return; 1813 return;
1812 } 1814 }
1813 if (frame->TokenPos() == Scanner::kDummyTokenIndex) { 1815 if (frame->TokenPos() == Scanner::kDummyTokenIndex) {
1814 return; 1816 return;
1815 } 1817 }
1816 1818
1817 if (FLAG_verbose_debug) { 1819 if (FLAG_verbose_debug) {
1818 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n", 1820 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n",
1819 String::Handle(frame->SourceUrl()).ToCString(), 1821 String::Handle(frame->SourceUrl()).ToCString(),
1820 frame->LineNumber(), 1822 frame->LineNumber(),
1821 String::Handle(frame->QualifiedFunctionName()).ToCString(), 1823 String::Handle(frame->QualifiedFunctionName()).ToCString(),
1822 frame->TokenPos()); 1824 frame->TokenPos());
1823 } 1825 }
1824 1826
1827 ASSERT(stack_trace_ == NULL);
1825 stack_trace_ = CollectStackTrace(); 1828 stack_trace_ = CollectStackTrace();
1826 SignalPausedEvent(frame, NULL); 1829 SignalPausedEvent(frame, NULL);
1827 1830
1828 RemoveInternalBreakpoints(); 1831 RemoveInternalBreakpoints();
1829 if (resume_action_ == kStepOver) { 1832 if (resume_action_ == kStepOver) {
1830 InstrumentForStepping(func); 1833 InstrumentForStepping(func);
1831 } else if (resume_action_ == kStepOut) { 1834 } else if (resume_action_ == kStepOut) {
1832 if (stack_trace_->Length() > 1) { 1835 if (stack_trace_->Length() > 1) {
1833 ActivationFrame* caller_frame = stack_trace_->FrameAt(1); 1836 ActivationFrame* caller_frame = stack_trace_->FrameAt(1);
1834 InstrumentForStepping(caller_frame->function()); 1837 InstrumentForStepping(caller_frame->function());
1835 } 1838 }
1836 } 1839 }
1837 stack_trace_ = NULL; 1840 stack_trace_ = NULL;
1838 } 1841 }
1839 1842
1840 1843
1841 void Debugger::SignalBpReached() { 1844 void Debugger::SignalBpReached() {
1842 // We ignore this breakpoint when the VM is executing code invoked 1845 // We ignore this breakpoint when the VM is executing code invoked
1843 // by the debugger to evaluate variables values, or when we see a nested 1846 // by the debugger to evaluate variables values, or when we see a nested
1844 // breakpoint or exception event. 1847 // breakpoint or exception event.
1845 if (ignore_breakpoints_ || in_event_notification_) { 1848 if (ignore_breakpoints_ || IsPaused()) {
1846 return; 1849 return;
1847 } 1850 }
1848 DebuggerStackTrace* stack_trace = CollectStackTrace(); 1851 DebuggerStackTrace* stack_trace = CollectStackTrace();
1849 ASSERT(stack_trace->Length() > 0); 1852 ASSERT(stack_trace->Length() > 0);
1850 ActivationFrame* top_frame = stack_trace->FrameAt(0); 1853 ActivationFrame* top_frame = stack_trace->FrameAt(0);
1851 ASSERT(top_frame != NULL); 1854 ASSERT(top_frame != NULL);
1852 CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc()); 1855 CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc());
1853 ASSERT(bpt != NULL); 1856 ASSERT(bpt != NULL);
1854 1857
1855 bool report_bp = true; 1858 bool report_bp = true;
1856 if (bpt->IsInternal() && !IsDebuggable(top_frame->function())) { 1859 if (bpt->IsInternal() && !IsDebuggable(top_frame->function())) {
1857 report_bp = false; 1860 report_bp = false;
1858 } 1861 }
1859 if (FLAG_verbose_debug) { 1862 if (FLAG_verbose_debug) {
1860 OS::Print(">>> %s %s breakpoint at %s:%" Pd " " 1863 OS::Print(">>> %s %s breakpoint at %s:%" Pd " "
1861 "(token %" Pd ") (address %#" Px ")\n", 1864 "(token %" Pd ") (address %#" Px ")\n",
1862 report_bp ? "hit" : "ignore", 1865 report_bp ? "hit" : "ignore",
1863 bpt->IsInternal() ? "internal" : "user", 1866 bpt->IsInternal() ? "internal" : "user",
1864 String::Handle(bpt->SourceUrl()).ToCString(), 1867 String::Handle(bpt->SourceUrl()).ToCString(),
1865 bpt->LineNumber(), 1868 bpt->LineNumber(),
1866 bpt->token_pos(), 1869 bpt->token_pos(),
1867 top_frame->pc()); 1870 top_frame->pc());
1868 } 1871 }
1869 1872
1870 if (report_bp && (event_handler_ != NULL)) { 1873 if (report_bp && (event_handler_ != NULL)) {
1874 ASSERT(stack_trace_ == NULL);
1871 stack_trace_ = stack_trace; 1875 stack_trace_ = stack_trace;
1872 SignalPausedEvent(top_frame, bpt->src_bpt_); 1876 SignalPausedEvent(top_frame, bpt->src_bpt_);
1873 stack_trace_ = NULL; 1877 stack_trace_ = NULL;
1874 } 1878 }
1875 1879
1876 Function& func_to_instrument = Function::Handle(); 1880 Function& func_to_instrument = Function::Handle();
1877 if (resume_action_ == kStepOver) { 1881 if (resume_action_ == kStepOver) {
1878 if (bpt->breakpoint_kind_ == PcDescriptors::kReturn) { 1882 if (bpt->breakpoint_kind_ == PcDescriptors::kReturn) {
1879 // Step over return is converted into a single step so we break at 1883 // Step over return is converted into a single step so we break at
1880 // the caller. 1884 // the caller.
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 } 2138 }
2135 2139
2136 2140
2137 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 2141 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
2138 ASSERT(bpt->next() == NULL); 2142 ASSERT(bpt->next() == NULL);
2139 bpt->set_next(code_breakpoints_); 2143 bpt->set_next(code_breakpoints_);
2140 code_breakpoints_ = bpt; 2144 code_breakpoints_ = bpt;
2141 } 2145 }
2142 2146
2143 } // namespace dart 2147 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698