| 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 "platform/address_sanitizer.h" | 7 #include "platform/address_sanitizer.h" |
| 8 | 8 |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| 11 #include "vm/debugger.h" | 11 #include "vm/debugger.h" |
| 12 #include "vm/flags.h" | 12 #include "vm/flags.h" |
| 13 #include "vm/object.h" | 13 #include "vm/object.h" |
| 14 #include "vm/object_store.h" | 14 #include "vm/object_store.h" |
| 15 #include "vm/stack_frame.h" | 15 #include "vm/stack_frame.h" |
| 16 #include "vm/stub_code.h" | 16 #include "vm/stub_code.h" |
| 17 #include "vm/symbols.h" | 17 #include "vm/symbols.h" |
| 18 #include "vm/tags.h" | 18 #include "vm/tags.h" |
| 19 | 19 |
| 20 namespace dart { | 20 namespace dart { |
| 21 | 21 |
| 22 // TODO(vegorov): Remove --abort_on_assertion_errors flag and associated | |
| 23 // infrastructure (dartbug.com/25753) | |
| 24 DEFINE_FLAG(bool, abort_on_assertion_errors, false, | |
| 25 "Abort on assertion and typecheck failures"); | |
| 26 DEFINE_FLAG(bool, print_stacktrace_at_throw, false, | 22 DEFINE_FLAG(bool, print_stacktrace_at_throw, false, |
| 27 "Prints a stack trace everytime a throw occurs."); | 23 "Prints a stack trace everytime a throw occurs."); |
| 28 | 24 |
| 29 | 25 |
| 30 const char* Exceptions::kCastErrorDstName = "type cast"; | 26 const char* Exceptions::kCastErrorDstName = "type cast"; |
| 31 | 27 |
| 32 | 28 |
| 33 class StacktraceBuilder : public ValueObject { | 29 class StacktraceBuilder : public ValueObject { |
| 34 public: | 30 public: |
| 35 StacktraceBuilder() { } | 31 StacktraceBuilder() { } |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 args.SetAt(2, Smi::Handle(Smi::New(column))); | 450 args.SetAt(2, Smi::Handle(Smi::New(column))); |
| 455 | 451 |
| 456 // Initialize '_srcType', '_dstType', '_dstName', and '_errorMsg'. | 452 // Initialize '_srcType', '_dstType', '_dstName', and '_errorMsg'. |
| 457 args.SetAt(3, src_type_name); | 453 args.SetAt(3, src_type_name); |
| 458 args.SetAt(4, dst_type_name); | 454 args.SetAt(4, dst_type_name); |
| 459 args.SetAt(5, dst_name); | 455 args.SetAt(5, dst_name); |
| 460 args.SetAt(6, error_msg); | 456 args.SetAt(6, error_msg); |
| 461 | 457 |
| 462 // Type errors in the core library may be difficult to diagnose. | 458 // Type errors in the core library may be difficult to diagnose. |
| 463 // Print type error information before throwing the error when debugging. | 459 // Print type error information before throwing the error when debugging. |
| 464 if (FLAG_print_stacktrace_at_throw || FLAG_abort_on_assertion_errors) { | 460 if (FLAG_print_stacktrace_at_throw) { |
| 465 if (!error_msg.IsNull()) { | 461 if (!error_msg.IsNull()) { |
| 466 OS::Print("%s\n", error_msg.ToCString()); | 462 OS::Print("%s\n", error_msg.ToCString()); |
| 467 } | 463 } |
| 468 OS::Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ", | 464 OS::Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ", |
| 469 String::Handle(script.url()).ToCString(), line, column); | 465 String::Handle(script.url()).ToCString(), line, column); |
| 470 if (!dst_name.IsNull() && (dst_name.Length() > 0)) { | 466 if (!dst_name.IsNull() && (dst_name.Length() > 0)) { |
| 471 OS::Print("type '%s' is not a subtype of type '%s' of '%s'.\n", | 467 OS::Print("type '%s' is not a subtype of type '%s' of '%s'.\n", |
| 472 src_type_name.ToCString(), | 468 src_type_name.ToCString(), |
| 473 dst_type_name.ToCString(), | 469 dst_type_name.ToCString(), |
| 474 dst_name.ToCString()); | 470 dst_name.ToCString()); |
| 475 } else { | 471 } else { |
| 476 OS::Print("type error.\n"); | 472 OS::Print("type error.\n"); |
| 477 } | 473 } |
| 478 } | 474 } |
| 479 | 475 |
| 480 if (FLAG_abort_on_assertion_errors) { | |
| 481 PrintStackTraceAndAbort("a type error"); | |
| 482 } | |
| 483 | |
| 484 // Throw TypeError or CastError instance. | 476 // Throw TypeError or CastError instance. |
| 485 Exceptions::ThrowByType(exception_type, args); | 477 Exceptions::ThrowByType(exception_type, args); |
| 486 UNREACHABLE(); | 478 UNREACHABLE(); |
| 487 } | 479 } |
| 488 | 480 |
| 489 | 481 |
| 490 void Exceptions::Throw(Thread* thread, const Instance& exception) { | 482 void Exceptions::Throw(Thread* thread, const Instance& exception) { |
| 491 // Do not notify debugger on stack overflow and out of memory exceptions. | 483 // Do not notify debugger on stack overflow and out of memory exceptions. |
| 492 // The VM would crash when the debugger calls back into the VM to | 484 // The VM would crash when the debugger calls back into the VM to |
| 493 // get values of variables. | 485 // get values of variables. |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 class_name = &Symbols::CyclicInitializationError(); | 657 class_name = &Symbols::CyclicInitializationError(); |
| 666 } | 658 } |
| 667 | 659 |
| 668 return DartLibraryCalls::InstanceCreate(library, | 660 return DartLibraryCalls::InstanceCreate(library, |
| 669 *class_name, | 661 *class_name, |
| 670 *constructor_name, | 662 *constructor_name, |
| 671 arguments); | 663 arguments); |
| 672 } | 664 } |
| 673 | 665 |
| 674 | 666 |
| 675 static bool IsLikelyInternalDart2JSCrash(const Stacktrace& stacktrace) { | |
| 676 Function& function = Function::Handle(); | |
| 677 String& name = String::Handle(); | |
| 678 for (intptr_t i = 0, len = stacktrace.Length(); i < len; i++) { | |
| 679 function = stacktrace.FunctionAtFrame(i); | |
| 680 name = function.QualifiedPrettyName(); | |
| 681 if (name.Equals("_CompilerDiagnosticReporter.withCurrentElement")) { | |
| 682 return true; | |
| 683 } | |
| 684 } | |
| 685 return false; | |
| 686 } | |
| 687 | |
| 688 | |
| 689 void Exceptions::PrintStackTraceAndAbort(const char* reason) { | |
| 690 const Stacktrace& stacktrace = Stacktrace::Handle(CurrentStacktrace()); | |
| 691 if (!IsLikelyInternalDart2JSCrash(stacktrace)) { | |
| 692 return; | |
| 693 } | |
| 694 | |
| 695 OS::PrintErr("\n\n\nAborting due to %s. Stacktrace:\n%s\n", | |
| 696 reason, | |
| 697 stacktrace.ToCString()); | |
| 698 OS::Abort(); | |
| 699 } | |
| 700 | |
| 701 } // namespace dart | 667 } // namespace dart |
| OLD | NEW |