| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/exceptions.h" | 5 #include "vm/exceptions.h" |
| 6 | 6 |
| 7 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
| 8 #include "vm/debugger.h" | 8 #include "vm/debugger.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| 11 #include "vm/stack_frame.h" | 11 #include "vm/stack_frame.h" |
| 12 #include "vm/stub_code.h" | 12 #include "vm/stub_code.h" |
| 13 #include "vm/symbols.h" | 13 #include "vm/symbols.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 DEFINE_FLAG(bool, print_stacktrace_at_throw, false, | 17 DEFINE_FLAG(bool, print_stacktrace_at_throw, false, |
| 18 "Prints a stack trace everytime a throw occurs."); | 18 "Prints a stack trace everytime a throw occurs."); |
| 19 | 19 |
| 20 | 20 |
| 21 const char* Exceptions::kCastExceptionDstName = "type cast"; | 21 const char* Exceptions::kCastExceptionDstName = "type cast"; |
| 22 | 22 |
| 23 | 23 |
| 24 // Iterate through the stack frames and try to find a frame with an | 24 // Iterate through the stack frames and try to find a frame with an |
| 25 // exception handler. Once found, set the pc, sp and fp so that execution | 25 // exception handler. Once found, set the pc, sp and fp so that execution |
| 26 // can continue in that frame. | 26 // can continue in that frame. |
| 27 static bool FindExceptionHandler(uword* handler_pc, | 27 static bool FindExceptionHandler(uword* handler_pc, |
| 28 uword* handler_sp, | 28 uword* handler_sp, |
| 29 uword* handler_fp, | 29 uword* handler_fp, |
| 30 GrowableArray<uword>* stack_frame_pcs, | |
| 31 const GrowableObjectArray& func_list, | 30 const GrowableObjectArray& func_list, |
| 32 const GrowableObjectArray& code_list) { | 31 const GrowableObjectArray& code_list, |
| 32 const GrowableObjectArray& pc_offset_list) { |
| 33 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); | 33 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); |
| 34 StackFrame* frame = frames.NextFrame(); | 34 StackFrame* frame = frames.NextFrame(); |
| 35 ASSERT(frame != NULL); | 35 ASSERT(frame != NULL); |
| 36 Function& func = Function::Handle(); | 36 Function& func = Function::Handle(); |
| 37 Code& code = Code::Handle(); | 37 Code& code = Code::Handle(); |
| 38 Smi& offset = Smi::Handle(); |
| 38 while (!frame->IsEntryFrame()) { | 39 while (!frame->IsEntryFrame()) { |
| 39 if (frame->IsDartFrame()) { | 40 if (frame->IsDartFrame()) { |
| 40 stack_frame_pcs->Add(frame->pc()); | |
| 41 func = frame->LookupDartFunction(); | 41 func = frame->LookupDartFunction(); |
| 42 code = frame->LookupDartCode(); | 42 code = frame->LookupDartCode(); |
| 43 offset = Smi::New(frame->pc() - code.EntryPoint()); |
| 43 func_list.Add(func); | 44 func_list.Add(func); |
| 44 code_list.Add(code); | 45 code_list.Add(code); |
| 46 pc_offset_list.Add(offset); |
| 45 if (frame->FindExceptionHandler(handler_pc)) { | 47 if (frame->FindExceptionHandler(handler_pc)) { |
| 46 *handler_sp = frame->sp(); | 48 *handler_sp = frame->sp(); |
| 47 *handler_fp = frame->fp(); | 49 *handler_fp = frame->fp(); |
| 48 return true; | 50 return true; |
| 49 } | 51 } |
| 50 } | 52 } |
| 51 frame = frames.NextFrame(); | 53 frame = frames.NextFrame(); |
| 52 ASSERT(frame != NULL); | 54 ASSERT(frame != NULL); |
| 53 } | 55 } |
| 54 ASSERT(frame->IsEntryFrame()); | 56 ASSERT(frame->IsEntryFrame()); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 static void ThrowExceptionHelper(const Instance& incoming_exception, | 138 static void ThrowExceptionHelper(const Instance& incoming_exception, |
| 137 const Instance& existing_stacktrace) { | 139 const Instance& existing_stacktrace) { |
| 138 Instance& exception = Instance::Handle(incoming_exception.raw()); | 140 Instance& exception = Instance::Handle(incoming_exception.raw()); |
| 139 if (exception.IsNull()) { | 141 if (exception.IsNull()) { |
| 140 GrowableArray<const Object*> arguments; | 142 GrowableArray<const Object*> arguments; |
| 141 exception ^= Exceptions::Create(Exceptions::kNullPointer, arguments); | 143 exception ^= Exceptions::Create(Exceptions::kNullPointer, arguments); |
| 142 } | 144 } |
| 143 uword handler_pc = 0; | 145 uword handler_pc = 0; |
| 144 uword handler_sp = 0; | 146 uword handler_sp = 0; |
| 145 uword handler_fp = 0; | 147 uword handler_fp = 0; |
| 146 GrowableArray<uword> stack_frame_pcs; | |
| 147 const GrowableObjectArray& func_list = | 148 const GrowableObjectArray& func_list = |
| 148 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 149 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 149 const GrowableObjectArray& code_list = | 150 const GrowableObjectArray& code_list = |
| 150 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 151 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 152 const GrowableObjectArray& pc_offset_list = |
| 153 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 151 bool handler_exists = FindExceptionHandler(&handler_pc, | 154 bool handler_exists = FindExceptionHandler(&handler_pc, |
| 152 &handler_sp, | 155 &handler_sp, |
| 153 &handler_fp, | 156 &handler_fp, |
| 154 &stack_frame_pcs, | |
| 155 func_list, | 157 func_list, |
| 156 code_list); | 158 code_list, |
| 159 pc_offset_list); |
| 157 // TODO(5411263): At some point we can optimize by figuring out if a | 160 // TODO(5411263): At some point we can optimize by figuring out if a |
| 158 // stack trace is needed based on whether the catch code specifies a | 161 // stack trace is needed based on whether the catch code specifies a |
| 159 // stack trace object or there is a rethrow in the catch clause. | 162 // stack trace object or there is a rethrow in the catch clause. |
| 160 Stacktrace& stacktrace = Stacktrace::Handle(); | 163 Stacktrace& stacktrace = Stacktrace::Handle(); |
| 161 if (!stack_frame_pcs.is_empty()) { | 164 if (pc_offset_list.Length() != 0) { |
| 162 if (existing_stacktrace.IsNull()) { | 165 if (existing_stacktrace.IsNull()) { |
| 163 stacktrace = Stacktrace::New(stack_frame_pcs, func_list, code_list); | 166 stacktrace = Stacktrace::New(func_list, code_list, pc_offset_list); |
| 164 } else { | 167 } else { |
| 165 stacktrace ^= existing_stacktrace.raw(); | 168 stacktrace ^= existing_stacktrace.raw(); |
| 166 stacktrace.Append(stack_frame_pcs, func_list, code_list); | 169 stacktrace.Append(func_list, code_list, pc_offset_list); |
| 167 } | 170 } |
| 168 } else { | 171 } else { |
| 169 stacktrace ^= existing_stacktrace.raw(); | 172 stacktrace ^= existing_stacktrace.raw(); |
| 170 } | 173 } |
| 171 if (FLAG_print_stacktrace_at_throw) { | 174 if (FLAG_print_stacktrace_at_throw) { |
| 172 OS::Print("Exception '%s' thrown:\n", exception.ToCString()); | 175 OS::Print("Exception '%s' thrown:\n", exception.ToCString()); |
| 173 OS::Print("%s\n", stacktrace.ToCString()); | 176 OS::Print("%s\n", stacktrace.ToCString()); |
| 174 } | 177 } |
| 175 if (handler_exists) { | 178 if (handler_exists) { |
| 176 // Found a dart handler for the exception, jump to it. | 179 // Found a dart handler for the exception, jump to it. |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 case kIsolateSpawn: | 435 case kIsolateSpawn: |
| 433 library = Library::IsolateLibrary(); | 436 library = Library::IsolateLibrary(); |
| 434 class_name = Symbols::New("IsolateSpawnException"); | 437 class_name = Symbols::New("IsolateSpawnException"); |
| 435 break; | 438 break; |
| 436 } | 439 } |
| 437 | 440 |
| 438 return DartLibraryCalls::ExceptionCreate(library, class_name, arguments); | 441 return DartLibraryCalls::ExceptionCreate(library, class_name, arguments); |
| 439 } | 442 } |
| 440 | 443 |
| 441 } // namespace dart | 444 } // namespace dart |
| OLD | NEW |