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

Unified Diff: runtime/vm/isolate.cc

Issue 11413101: Added support for isolate unhandled exceptions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/isolate.cc
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 6b9178d0b55bd32e7099967d285d0823738ccd6c..5ce67b375990254cbd809ba70c09e782cf420e95 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -41,13 +41,14 @@ class IsolateMessageHandler : public MessageHandler {
const char* name() const;
void MessageNotify(Message::Priority priority);
bool HandleMessage(Message* message);
-
#if defined(DEBUG)
// Check that it is safe to access this handler.
void CheckAccess();
#endif
bool IsCurrentIsolate() const;
virtual Isolate* GetIsolate() const { return isolate_; }
+ bool UnhandledExceptionCallbackHandler(const Object& message,
+ const UnhandledException& error);
private:
Isolate* isolate_;
@@ -101,22 +102,74 @@ bool IsolateMessageHandler::HandleMessage(Message* message) {
Instance& msg = Instance::Handle();
msg ^= msg_obj.raw(); // Can't use Instance::Cast because may be null.
+ bool success = true;
if (message->IsOOB()) {
// For now the only OOB messages are Mirrors messages.
HandleMirrorsMessage(isolate_, message->reply_port(), msg);
- delete message;
} else {
const Object& result = Object::Handle(
DartLibraryCalls::HandleMessage(
message->dest_port(), message->reply_port(), msg));
- delete message;
if (result.IsError()) {
isolate_->object_store()->set_sticky_error(Error::Cast(result));
- return false;
+ if (result.IsUnhandledException()) {
+ const UnhandledException& error = UnhandledException::Cast(result);
+ RawInstance* exception = error.exception();
+ if ((exception != isolate_->object_store()->out_of_memory()) &&
+ (exception != isolate_->object_store()->stack_overflow())) {
+ success = UnhandledExceptionCallbackHandler(msg, error);
+ if (!success && (Isolate::UnhandledExceptionCallback() != NULL)) {
+ // Notify embedder that an unhandled exception occurred.
+ Dart_EnterScope();
+ Dart_Handle error_handle = Api::NewHandle(isolate_, error.raw());
+ (Isolate::UnhandledExceptionCallback())(error_handle);
+ // TODO(tball): add some sort of blocker to ensure embedder
+ // doesn't run any more code on this isolate.
+ Dart_ExitScope();
+ }
+ }
+ }
siva 2012/11/21 00:45:04 I presume a return of success == true would keep t
Tom Ball 2012/11/21 05:22:38 PTAL -- I refactored it and fixed when the Unhandl
+ } else {
+ ASSERT(result.IsNull());
}
- ASSERT(result.IsNull());
}
- return true;
+ delete message;
+ return success;
+}
+
+
+bool IsolateMessageHandler::UnhandledExceptionCallbackHandler(
+ const Object& message, const UnhandledException& error) {
+ RawInstance* callback =
+ isolate_->object_store()->unhandled_exception_closure();
+ Instance& closure = Instance::Handle(callback);
+ if (closure.IsNull()) {
+ return false; // Error wasn't handled by callback.
+ }
+ const Instance& stacktrace =
+ Instance::Handle(isolate_, error.stacktrace());
+
+ // Wrap these args into an IsolateUncaughtException object.
+ GrowableArray<const Object*> exception_args(3);
+ exception_args.Add(&message);
+ exception_args.Add(&error);
+ exception_args.Add(&stacktrace);
+ Object& exception = Object::Handle();
+ exception = Exceptions::Create(Exceptions::kIsolateUnhandledException,
+ exception_args);
+ if (exception.IsError()) {
+ return false;
+ }
+
+ // Invoke script's callback closure.
+ GrowableArray<const Object*> callback_args(1);
+ callback_args.Add(&exception);
+ const Array& kNoArgumentNames = Array::Handle(isolate_);
+ RawObject* response = DartEntry::InvokeClosure(closure,
+ callback_args,
+ kNoArgumentNames);
+ // TODO(tball): log any nested exceptions.
+ return (response == Bool::True());
}
@@ -446,6 +499,8 @@ void Isolate::Shutdown() {
Dart_IsolateCreateCallback Isolate::create_callback_ = NULL;
Dart_IsolateInterruptCallback Isolate::interrupt_callback_ = NULL;
+Dart_IsolateUnhandledExceptionCallback
+ Isolate::unhandled_exception_callback_ = NULL;
Dart_IsolateShutdownCallback Isolate::shutdown_callback_ = NULL;
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/object_store.h » ('j') | sdk/lib/isolate/base.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698