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

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

Issue 23000011: Fix debugger stack traces (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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') | runtime/vm/debugger_api_impl.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 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 288
289 289
290 void ActivationFrame::GetVarDescriptors() { 290 void ActivationFrame::GetVarDescriptors() {
291 if (var_descriptors_.IsNull()) { 291 if (var_descriptors_.IsNull()) {
292 var_descriptors_ = code().var_descriptors(); 292 var_descriptors_ = code().var_descriptors();
293 ASSERT(!var_descriptors_.IsNull()); 293 ASSERT(!var_descriptors_.IsNull());
294 } 294 }
295 } 295 }
296 296
297 297
298 bool ActivationFrame::IsDebuggable() const {
299 return Debugger::IsDebuggable(function());
300 }
301
302
298 // Calculate the context level at the current token index of the frame. 303 // Calculate the context level at the current token index of the frame.
299 intptr_t ActivationFrame::ContextLevel() { 304 intptr_t ActivationFrame::ContextLevel() {
300 if (context_level_ < 0 && !ctx_.IsNull()) { 305 if (context_level_ < 0 && !ctx_.IsNull()) {
301 ASSERT(!code_.is_optimized()); 306 ASSERT(!code_.is_optimized());
302 context_level_ = 0; 307 context_level_ = 0;
303 intptr_t pc_desc_idx = PcDescIndex(); 308 intptr_t pc_desc_idx = PcDescIndex();
304 // TODO(hausner): What to do if there is no descriptor entry 309 // TODO(hausner): What to do if there is no descriptor entry
305 // for the code position of the frame? For now say we are at context 310 // for the code position of the frame? For now say we are at context
306 // level 0. 311 // level 0.
307 if (pc_desc_idx < 0) { 312 if (pc_desc_idx < 0) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 return Context::null(); 375 return Context::null();
371 } 376 }
372 377
373 378
374 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( 379 ActivationFrame* DebuggerStackTrace::GetHandlerFrame(
375 const Instance& exc_obj) const { 380 const Instance& exc_obj) const {
376 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); 381 ExceptionHandlers& handlers = ExceptionHandlers::Handle();
377 Array& handled_types = Array::Handle(); 382 Array& handled_types = Array::Handle();
378 AbstractType& type = Type::Handle(); 383 AbstractType& type = Type::Handle();
379 const TypeArguments& no_instantiator = TypeArguments::Handle(); 384 const TypeArguments& no_instantiator = TypeArguments::Handle();
380 for (int frame_index = 0; frame_index < Length(); frame_index++) { 385 for (int frame_index = 0; frame_index < UnfilteredLength(); frame_index++) {
381 ActivationFrame* frame = trace_[frame_index]; 386 ActivationFrame* frame = UnfilteredFrameAt(frame_index);
382 intptr_t try_index = frame->TryIndex(); 387 intptr_t try_index = frame->TryIndex();
383 if (try_index < 0) continue; 388 if (try_index < 0) continue;
384 handlers = frame->code().exception_handlers(); 389 handlers = frame->code().exception_handlers();
385 ASSERT(!handlers.IsNull()); 390 ASSERT(!handlers.IsNull());
386 intptr_t num_handlers_checked = 0; 391 intptr_t num_handlers_checked = 0;
387 while (try_index >= 0) { 392 while (try_index >= 0) {
388 // Detect circles in the exception handler data. 393 // Detect circles in the exception handler data.
389 num_handlers_checked++; 394 num_handlers_checked++;
390 ASSERT(num_handlers_checked <= handlers.Length()); 395 ASSERT(num_handlers_checked <= handlers.Length());
391 handled_types = handlers.GetHandledTypes(try_index); 396 handled_types = handlers.GetHandledTypes(try_index);
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 OS::SNPrint(NULL, 0, kFormat, func_name, url.ToCString(), line); 578 OS::SNPrint(NULL, 0, kFormat, func_name, url.ToCString(), line);
574 len++; // String terminator. 579 len++; // String terminator.
575 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 580 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
576 OS::SNPrint(chars, len, kFormat, func_name, url.ToCString(), line); 581 OS::SNPrint(chars, len, kFormat, func_name, url.ToCString(), line);
577 return chars; 582 return chars;
578 } 583 }
579 584
580 585
581 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { 586 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) {
582 trace_.Add(frame); 587 trace_.Add(frame);
588 if (frame->IsDebuggable()) {
589 user_trace_.Add(frame);
590 }
583 } 591 }
584 592
585 593
586 static bool IsSafePoint(PcDescriptors::Kind kind) { 594 static bool IsSafePoint(PcDescriptors::Kind kind) {
587 return ((kind == PcDescriptors::kIcCall) || 595 return ((kind == PcDescriptors::kIcCall) ||
588 (kind == PcDescriptors::kOptStaticCall) || 596 (kind == PcDescriptors::kOptStaticCall) ||
589 (kind == PcDescriptors::kUnoptStaticCall) || 597 (kind == PcDescriptors::kUnoptStaticCall) ||
590 (kind == PcDescriptors::kClosureCall) || 598 (kind == PcDescriptors::kClosureCall) ||
591 (kind == PcDescriptors::kReturn) || 599 (kind == PcDescriptors::kReturn) ||
592 (kind == PcDescriptors::kRuntimeCall)); 600 (kind == PcDescriptors::kRuntimeCall));
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 } 978 }
971 } 979 }
972 if (optimized_frame_found || code.is_optimized()) { 980 if (optimized_frame_found || code.is_optimized()) {
973 // Set context to null, to avoid returning bad context variable values. 981 // Set context to null, to avoid returning bad context variable values.
974 activation->SetContext(Context::Handle()); 982 activation->SetContext(Context::Handle());
975 optimized_frame_found = true; 983 optimized_frame_found = true;
976 } else { 984 } else {
977 ASSERT(!ctx.IsNull()); 985 ASSERT(!ctx.IsNull());
978 activation->SetContext(ctx); 986 activation->SetContext(ctx);
979 } 987 }
980 // Check if frame is a debuggable function. 988 stack_trace->AddActivation(activation);
981 if (IsDebuggable(activation->function())) {
982 stack_trace->AddActivation(activation);
983 }
984 callee_activation = activation; 989 callee_activation = activation;
985 // Get caller's context if this function saved it on entry. 990 // Get caller's context if this function saved it on entry.
986 ctx = activation->GetSavedEntryContext(ctx); 991 ctx = activation->GetSavedEntryContext(ctx);
987 } else if (frame->IsEntryFrame()) { 992 } else if (frame->IsEntryFrame()) {
988 ctx = reinterpret_cast<EntryFrame*>(frame)->SavedContext(); 993 ctx = reinterpret_cast<EntryFrame*>(frame)->SavedContext();
989 callee_activation = NULL; 994 callee_activation = NULL;
990 } 995 }
991 } 996 }
992 return stack_trace; 997 return stack_trace;
993 } 998 }
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
1596 } 1601 }
1597 1602
1598 stack_trace_ = CollectStackTrace(); 1603 stack_trace_ = CollectStackTrace();
1599 SignalPausedEvent(frame); 1604 SignalPausedEvent(frame);
1600 1605
1601 RemoveInternalBreakpoints(); 1606 RemoveInternalBreakpoints();
1602 if (resume_action_ == kStepOver) { 1607 if (resume_action_ == kStepOver) {
1603 InstrumentForStepping(func); 1608 InstrumentForStepping(func);
1604 } else if (resume_action_ == kStepOut) { 1609 } else if (resume_action_ == kStepOut) {
1605 if (stack_trace_->Length() > 1) { 1610 if (stack_trace_->Length() > 1) {
1606 ActivationFrame* caller_frame = stack_trace_->ActivationFrameAt(1); 1611 ActivationFrame* caller_frame = stack_trace_->FrameAt(1);
1607 InstrumentForStepping(caller_frame->function()); 1612 InstrumentForStepping(caller_frame->function());
1608 } 1613 }
1609 } 1614 }
1610 stack_trace_ = NULL; 1615 stack_trace_ = NULL;
1611 } 1616 }
1612 1617
1613 1618
1614 void Debugger::SignalBpReached() { 1619 void Debugger::SignalBpReached() {
1615 // We ignore this breakpoint when the VM is executing code invoked 1620 // We ignore this breakpoint when the VM is executing code invoked
1616 // by the debugger to evaluate variables values, or when we see a nested 1621 // by the debugger to evaluate variables values, or when we see a nested
1617 // breakpoint or exception event. 1622 // breakpoint or exception event.
1618 if (ignore_breakpoints_ || in_event_notification_) { 1623 if (ignore_breakpoints_ || in_event_notification_) {
1619 return; 1624 return;
1620 } 1625 }
1621 DebuggerStackTrace* stack_trace = CollectStackTrace(); 1626 DebuggerStackTrace* stack_trace = CollectStackTrace();
1622 ASSERT(stack_trace->Length() > 0); 1627 ASSERT(stack_trace->UnfilteredLength() > 0);
1623 ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0); 1628 ActivationFrame* top_frame = stack_trace->UnfilteredFrameAt(0);
1624 ASSERT(top_frame != NULL); 1629 ASSERT(top_frame != NULL);
1625 CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc()); 1630 CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc());
1626 ASSERT(bpt != NULL); 1631 ASSERT(bpt != NULL);
1627 1632
1628 bool report_bp = true; 1633 bool report_bp = true;
1629 if (bpt->IsInternal() && !IsDebuggable(top_frame->function())) { 1634 if (bpt->IsInternal() && !IsDebuggable(top_frame->function())) {
1630 report_bp = false; 1635 report_bp = false;
1631 } 1636 }
1632 if (FLAG_verbose_debug) { 1637 if (FLAG_verbose_debug) {
1633 OS::Print(">>> %s %s breakpoint at %s:%" Pd " " 1638 OS::Print(">>> %s %s breakpoint at %s:%" Pd " "
(...skipping 16 matching lines...) Expand all
1650 if (resume_action_ == kStepOver) { 1655 if (resume_action_ == kStepOver) {
1651 if (bpt->breakpoint_kind_ == PcDescriptors::kReturn) { 1656 if (bpt->breakpoint_kind_ == PcDescriptors::kReturn) {
1652 // Step over return is converted into a single step so we break at 1657 // Step over return is converted into a single step so we break at
1653 // the caller. 1658 // the caller.
1654 SetSingleStep(); 1659 SetSingleStep();
1655 } else { 1660 } else {
1656 func_to_instrument = bpt->function(); 1661 func_to_instrument = bpt->function();
1657 } 1662 }
1658 } else if (resume_action_ == kStepOut) { 1663 } else if (resume_action_ == kStepOut) {
1659 if (stack_trace->Length() > 1) { 1664 if (stack_trace->Length() > 1) {
1660 ActivationFrame* caller_frame = stack_trace->ActivationFrameAt(1); 1665 ActivationFrame* caller_frame = stack_trace->FrameAt(1);
1661 func_to_instrument = caller_frame->function().raw(); 1666 func_to_instrument = caller_frame->function().raw();
1662 } 1667 }
1663 } else { 1668 } else {
1664 ASSERT((resume_action_ == kContinue) || (resume_action_ == kSingleStep)); 1669 ASSERT((resume_action_ == kContinue) || (resume_action_ == kSingleStep));
1665 // Nothing to do here. Any potential instrumentation will be removed 1670 // Nothing to do here. Any potential instrumentation will be removed
1666 // below. Single stepping is handled by the single step callback. 1671 // below. Single stepping is handled by the single step callback.
1667 } 1672 }
1668 1673
1669 if (func_to_instrument.IsNull() || 1674 if (func_to_instrument.IsNull() ||
1670 (func_to_instrument.raw() != bpt->function())) { 1675 (func_to_instrument.raw() != bpt->function())) {
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1865 } 1870 }
1866 1871
1867 1872
1868 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 1873 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
1869 ASSERT(bpt->next() == NULL); 1874 ASSERT(bpt->next() == NULL);
1870 bpt->set_next(code_breakpoints_); 1875 bpt->set_next(code_breakpoints_);
1871 code_breakpoints_ = bpt; 1876 code_breakpoints_ = bpt;
1872 } 1877 }
1873 1878
1874 } // namespace dart 1879 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698