Chromium Code Reviews| Index: runtime/vm/debugger.cc |
| =================================================================== |
| --- runtime/vm/debugger.cc (revision 17157) |
| +++ runtime/vm/debugger.cc (working copy) |
| @@ -301,6 +301,12 @@ |
| } |
| +intptr_t ActivationFrame::TryIndex() { |
| + intptr_t desc_index = PcDescIndex(); |
| + return pc_desc_.TryIndex(desc_index); |
| +} |
| + |
| + |
| intptr_t ActivationFrame::LineNumber() { |
| // Compute line number lazily since it causes scanning of the script. |
| if (line_number_ < 0) { |
| @@ -372,6 +378,57 @@ |
| } |
| +// TODO(hausner): Eliminate this helper function by sorting the |
| +// ExceptionHandlers entries by try_index and eliminating |
| +// the try_index field altogether. |
| +static intptr_t FindTryIndex(const ExceptionHandlers& handlers, |
| + intptr_t try_index) { |
| + intptr_t len = handlers.Length(); |
| + for (int i = 0; i < len; i++) { |
| + if (handlers.TryIndex(i) == try_index) return i; |
| + } |
| + UNREACHABLE(); |
| + return -1; |
| +} |
| + |
| + |
| +ActivationFrame* DebuggerStackTrace::GetHandlerFrame( |
| + const Instance& exc_obj) const { |
| + ExceptionHandlers& handlers = ExceptionHandlers::Handle(); |
| + Array& handled_types = Array::Handle(); |
| + Type& type = Type::Handle(); |
| + const TypeArguments& no_instantiator = TypeArguments::Handle(); |
| + for (int frame_index = 0; frame_index < Length(); frame_index++) { |
| + ActivationFrame* frame = trace_[frame_index]; |
| + intptr_t try_index = frame->TryIndex(); |
| + if (try_index < 0) continue; |
| + const Code& code = frame->DartCode(); |
| + handlers = code.exception_handlers(); |
| + ASSERT(!handlers.IsNull()); |
| + intptr_t num_handlers_checked = 0; |
| + while (try_index >= 0) { |
| + intptr_t i = FindTryIndex(handlers, try_index); |
| + // Detect circles in the exception handler data. |
| + num_handlers_checked++; |
| + ASSERT(num_handlers_checked <= handlers.Length()); |
| + handled_types = handlers.GetHandledTypes(i); |
| + intptr_t num_types = handled_types.Length(); |
|
srdjan
2013/01/16 21:12:16
const
hausner
2013/01/16 22:07:25
Done.
|
| + for (int k = 0; k < num_types; k++) { |
| + type ^= handled_types.At(k); |
| + ASSERT(!type.IsNull()); |
| + if (type.IsDynamicType()) return frame; |
| + if (type.IsMalformed()) continue; |
|
regis
2013/01/16 21:06:36
If the type is malformed, the test at run time wil
hausner
2013/01/16 22:07:25
I think 'continue' to the next type check is corre
|
| + if (exc_obj.IsInstanceOf(type, no_instantiator, NULL)) { |
|
regis
2013/01/16 21:06:36
How about a comment indicating you may get a false
hausner
2013/01/16 22:07:25
Done.
|
| + return frame; |
| + } |
| + } |
| + try_index = handlers.OuterTryIndex(i); |
| + } |
| + } |
| + return NULL; |
| +} |
| + |
| + |
| void ActivationFrame::GetDescIndices() { |
| if (vars_initialized_) { |
| return; |
| @@ -866,31 +923,29 @@ |
| } |
| -// TODO(hausner): Determine whether the exception is handled or not. |
| bool Debugger::ShouldPauseOnException(DebuggerStackTrace* stack_trace, |
| - const Object& exc) { |
| + const Instance& exc) { |
| if (exc_pause_info_ == kNoPauseOnExceptions) { |
| return false; |
| } |
| - if ((exc_pause_info_ & kPauseOnAllExceptions) != 0) { |
| + if (exc_pause_info_ == kPauseOnAllExceptions) { |
| return true; |
| } |
| - // Assume TypeError and AssertionError exceptions are unhandled. |
| - const Class& exc_class = Class::Handle(exc.clazz()); |
| - const String& class_name = String::Handle(exc_class.Name()); |
| - // TODO(hausner): Note the poor man's type test. This code will go |
| - // away when we have a way to determine whether an exception is unhandled. |
| - if (class_name.Equals("TypeErrorImplementation")) { |
| + ASSERT(exc_pause_info_ == kPauseOnUnhandledExceptions); |
| + ActivationFrame* handler_frame = stack_trace->GetHandlerFrame(exc); |
| + if (handler_frame == NULL) { |
| + // Did not find an exception handler that catches this exception. |
| + // Note that this check is not precise, since we can't check |
| + // uninstantiated types, i.e. types containing type parameters. |
| + // Thus, we may report an exception as unhandled when in fact |
| + // it will be caught once we unwind the stack. |
| return true; |
| } |
| - if (class_name.Equals("AssertionErrorImplementation")) { |
| - return true; |
| - } |
| return false; |
| } |
| -void Debugger::SignalExceptionThrown(const Object& exc) { |
| +void Debugger::SignalExceptionThrown(const Instance& exc) { |
| // We ignore this exception event when the VM is executing code invoked |
| // by the debugger to evaluate variables values, when we see a nested |
| // breakpoint or exception event, or if the debugger is not |