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

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

Issue 796003006: - Remove entirely disconnected unhandled exception handler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 11 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/isolate.h ('k') | runtime/vm/object_store.h » ('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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/isolate.h" 5 #include "vm/isolate.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "platform/json.h" 9 #include "platform/json.h"
10 #include "vm/code_observers.h" 10 #include "vm/code_observers.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 const char* name() const; 90 const char* name() const;
91 void MessageNotify(Message::Priority priority); 91 void MessageNotify(Message::Priority priority);
92 bool HandleMessage(Message* message); 92 bool HandleMessage(Message* message);
93 93
94 #if defined(DEBUG) 94 #if defined(DEBUG)
95 // Check that it is safe to access this handler. 95 // Check that it is safe to access this handler.
96 void CheckAccess(); 96 void CheckAccess();
97 #endif 97 #endif
98 bool IsCurrentIsolate() const; 98 bool IsCurrentIsolate() const;
99 virtual Isolate* isolate() const { return isolate_; } 99 virtual Isolate* isolate() const { return isolate_; }
100 bool UnhandledExceptionCallbackHandler(const Object& message,
101 const UnhandledException& error);
102 100
103 private: 101 private:
104 // Keep in sync with isolate_patch.dart. 102 // Keep in sync with isolate_patch.dart.
105 enum { 103 enum {
106 kPauseMsg = 1, 104 kPauseMsg = 1,
107 kResumeMsg = 2, 105 kResumeMsg = 2,
108 kPingMsg = 3, 106 kPingMsg = 3,
109 kKillMsg = 4, 107 kKillMsg = 4,
110 108
111 kImmediateAction = 0, 109 kImmediateAction = 0,
112 kBeforeNextEventAction = 1, 110 kBeforeNextEventAction = 1,
113 kAsEventAction = 2 111 kAsEventAction = 2
114 }; 112 };
115 113
116 // A result of false indicates that the isolate should terminate the 114 // A result of false indicates that the isolate should terminate the
117 // processing of further events. 115 // processing of further events.
118 bool HandleLibMessage(const Array& message); 116 bool HandleLibMessage(const Array& message);
119 117
120 bool ProcessUnhandledException(const Object& message, const Error& result); 118 bool ProcessUnhandledException(const Error& result);
121 RawFunction* ResolveCallbackFunction();
122 Isolate* isolate_; 119 Isolate* isolate_;
123 }; 120 };
124 121
125 122
126 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate) 123 IsolateMessageHandler::IsolateMessageHandler(Isolate* isolate)
127 : isolate_(isolate) { 124 : isolate_(isolate) {
128 } 125 }
129 126
130 127
131 IsolateMessageHandler::~IsolateMessageHandler() { 128 IsolateMessageHandler::~IsolateMessageHandler() {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 262
266 // If the message is in band we lookup the handler to dispatch to. If the 263 // If the message is in band we lookup the handler to dispatch to. If the
267 // receive port was closed, we drop the message without deserializing it. 264 // receive port was closed, we drop the message without deserializing it.
268 // Illegal port is a special case for artificially enqueued isolate library 265 // Illegal port is a special case for artificially enqueued isolate library
269 // messages which are handled in C++ code below. 266 // messages which are handled in C++ code below.
270 Object& msg_handler = Object::Handle(I); 267 Object& msg_handler = Object::Handle(I);
271 if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) { 268 if (!message->IsOOB() && (message->dest_port() != Message::kIllegalPort)) {
272 msg_handler = DartLibraryCalls::LookupHandler(message->dest_port()); 269 msg_handler = DartLibraryCalls::LookupHandler(message->dest_port());
273 if (msg_handler.IsError()) { 270 if (msg_handler.IsError()) {
274 delete message; 271 delete message;
275 return ProcessUnhandledException(Object::null_instance(), 272 return ProcessUnhandledException(Error::Cast(msg_handler));
276 Error::Cast(msg_handler));
277 } 273 }
278 if (msg_handler.IsNull()) { 274 if (msg_handler.IsNull()) {
279 // If the port has been closed then the message will be dropped at this 275 // If the port has been closed then the message will be dropped at this
280 // point. Make sure to post to the delivery failure port in that case. 276 // point. Make sure to post to the delivery failure port in that case.
281 if (message->RedirectToDeliveryFailurePort()) { 277 if (message->RedirectToDeliveryFailurePort()) {
282 PortMap::PostMessage(message); 278 PortMap::PostMessage(message);
283 } else { 279 } else {
284 delete message; 280 delete message;
285 } 281 }
286 return true; 282 return true;
287 } 283 }
288 } 284 }
289 285
290 // Parse the message. 286 // Parse the message.
291 SnapshotReader reader(message->data(), message->len(), Snapshot::kMessage, I); 287 SnapshotReader reader(message->data(), message->len(), Snapshot::kMessage, I);
292 const Object& msg_obj = Object::Handle(I, reader.ReadObject()); 288 const Object& msg_obj = Object::Handle(I, reader.ReadObject());
293 if (msg_obj.IsError()) { 289 if (msg_obj.IsError()) {
294 // An error occurred while reading the message. 290 // An error occurred while reading the message.
295 delete message; 291 delete message;
296 return ProcessUnhandledException(Object::null_instance(), 292 return ProcessUnhandledException(Error::Cast(msg_obj));
297 Error::Cast(msg_obj));
298 } 293 }
299 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) { 294 if (!msg_obj.IsNull() && !msg_obj.IsInstance()) {
300 // TODO(turnidge): We need to decide what an isolate does with 295 // TODO(turnidge): We need to decide what an isolate does with
301 // malformed messages. If they (eventually) come from a remote 296 // malformed messages. If they (eventually) come from a remote
302 // machine, then it might make sense to drop the message entirely. 297 // machine, then it might make sense to drop the message entirely.
303 // In the case that the message originated locally, which is 298 // In the case that the message originated locally, which is
304 // always true for now, then this should never occur. 299 // always true for now, then this should never occur.
305 UNREACHABLE(); 300 UNREACHABLE();
306 } 301 }
307 302
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 if (oob_tag.IsSmi() && 344 if (oob_tag.IsSmi() &&
350 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) { 345 (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) {
351 success = HandleLibMessage(Array::Cast(msg_arr)); 346 success = HandleLibMessage(Array::Cast(msg_arr));
352 } 347 }
353 } 348 }
354 } 349 }
355 } else { 350 } else {
356 const Object& result = Object::Handle(I, 351 const Object& result = Object::Handle(I,
357 DartLibraryCalls::HandleMessage(msg_handler, msg)); 352 DartLibraryCalls::HandleMessage(msg_handler, msg));
358 if (result.IsError()) { 353 if (result.IsError()) {
359 success = ProcessUnhandledException(msg, Error::Cast(result)); 354 success = ProcessUnhandledException(Error::Cast(result));
360 } else { 355 } else {
361 ASSERT(result.IsNull()); 356 ASSERT(result.IsNull());
362 } 357 }
363 } 358 }
364 delete message; 359 delete message;
365 return success; 360 return success;
366 } 361 }
367 362
368 363
369 RawFunction* IsolateMessageHandler::ResolveCallbackFunction() {
370 ASSERT(I->object_store()->unhandled_exception_handler() != NULL);
371 String& callback_name = String::Handle(I);
372 if (I->object_store()->unhandled_exception_handler() != String::null()) {
373 callback_name = I->object_store()->unhandled_exception_handler();
374 } else {
375 callback_name = String::New("_unhandledExceptionCallback");
376 }
377 Library& lib = Library::Handle(I, I->object_store()->isolate_library());
378 Function& func = Function::Handle(I, lib.LookupLocalFunction(callback_name));
379 if (func.IsNull()) {
380 lib = I->object_store()->root_library();
381 // Note: bootstrap code in builtin library may attempt to resolve a
382 // callback function before the script is fully loaded, in which case
383 // the root library may not be registered yet.
384 if (!lib.IsNull()) {
385 func = lib.LookupLocalFunction(callback_name);
386 }
387 }
388 return func.raw();
389 }
390
391
392 bool IsolateMessageHandler::UnhandledExceptionCallbackHandler(
393 const Object& message, const UnhandledException& error) {
394 const Instance& cause = Instance::Handle(I, error.exception());
395 const Instance& stacktrace = Instance::Handle(I, error.stacktrace());
396
397 // Wrap these args into an IsolateUncaughtException object.
398 const Array& exception_args = Array::Handle(I, Array::New(3));
399 exception_args.SetAt(0, message);
400 exception_args.SetAt(1, cause);
401 exception_args.SetAt(2, stacktrace);
402 const Object& exception = Object::Handle(I,
403 Exceptions::Create(Exceptions::kIsolateUnhandledException,
404 exception_args));
405 if (exception.IsError()) {
406 return false;
407 }
408 ASSERT(exception.IsInstance());
409
410 // Invoke script's callback function.
411 Object& function = Object::Handle(I, ResolveCallbackFunction());
412 if (function.IsNull() || function.IsError()) {
413 return false;
414 }
415 const Array& callback_args = Array::Handle(I, Array::New(1));
416 callback_args.SetAt(0, exception);
417 const Object& result = Object::Handle(I,
418 DartEntry::InvokeFunction(Function::Cast(function), callback_args));
419 if (result.IsError()) {
420 const Error& err = Error::Cast(result);
421 OS::PrintErr("failed calling unhandled exception callback: %s\n",
422 err.ToErrorCString());
423 return false;
424 }
425
426 ASSERT(result.IsBool());
427 bool continue_from_exception = Bool::Cast(result).value();
428 if (continue_from_exception) {
429 I->object_store()->clear_sticky_error();
430 }
431 return continue_from_exception;
432 }
433
434 #if defined(DEBUG) 364 #if defined(DEBUG)
435 void IsolateMessageHandler::CheckAccess() { 365 void IsolateMessageHandler::CheckAccess() {
436 ASSERT(IsCurrentIsolate()); 366 ASSERT(IsCurrentIsolate());
437 } 367 }
438 #endif 368 #endif
439 369
440 370
441 bool IsolateMessageHandler::IsCurrentIsolate() const { 371 bool IsolateMessageHandler::IsCurrentIsolate() const {
442 return (I == Isolate::Current()); 372 return (I == Isolate::Current());
443 } 373 }
444 374
445 375
446 bool IsolateMessageHandler::ProcessUnhandledException( 376 bool IsolateMessageHandler::ProcessUnhandledException(const Error& result) {
447 const Object& message, const Error& result) { 377 // Notify the debugger about specific unhandled exceptions which are withheld
378 // when being thrown.
448 if (result.IsUnhandledException()) { 379 if (result.IsUnhandledException()) {
449 // Invoke the isolate's uncaught exception handler, if it exists.
450 const UnhandledException& error = UnhandledException::Cast(result); 380 const UnhandledException& error = UnhandledException::Cast(result);
451 RawInstance* exception = error.exception(); 381 RawInstance* exception = error.exception();
452 if ((exception == I->object_store()->out_of_memory()) || 382 if ((exception == I->object_store()->out_of_memory()) ||
453 (exception == I->object_store()->stack_overflow())) { 383 (exception == I->object_store()->stack_overflow())) {
454 // We didn't notify the debugger when the stack was full. Do it now. 384 // We didn't notify the debugger when the stack was full. Do it now.
455 I->debugger()->SignalExceptionThrown(Instance::Handle(exception)); 385 I->debugger()->SignalExceptionThrown(Instance::Handle(exception));
456 } 386 }
457 if ((exception != I->object_store()->out_of_memory()) &&
458 (exception != I->object_store()->stack_overflow())) {
459 if (UnhandledExceptionCallbackHandler(message, error)) {
460 return true;
461 }
462 }
463 } 387 }
464 388
465 // Invoke the isolate's unhandled exception callback if there is one. 389 // Invoke the isolate's unhandled exception callback if there is one.
466 if (Isolate::UnhandledExceptionCallback() != NULL) { 390 if (Isolate::UnhandledExceptionCallback() != NULL) {
467 Dart_EnterScope(); 391 Dart_EnterScope();
468 Dart_Handle error = Api::NewHandle(I, result.raw()); 392 Dart_Handle error = Api::NewHandle(I, result.raw());
469 (Isolate::UnhandledExceptionCallback())(error); 393 (Isolate::UnhandledExceptionCallback())(error);
470 Dart_ExitScope(); 394 Dart_ExitScope();
471 } 395 }
472 396
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 } 846 }
923 { 847 {
924 StartIsolateScope start_scope(isolate); 848 StartIsolateScope start_scope(isolate);
925 StackZone zone(isolate); 849 StackZone zone(isolate);
926 HandleScope handle_scope(isolate); 850 HandleScope handle_scope(isolate);
927 if (!ClassFinalizer::ProcessPendingClasses()) { 851 if (!ClassFinalizer::ProcessPendingClasses()) {
928 // Error is in sticky error already. 852 // Error is in sticky error already.
929 return false; 853 return false;
930 } 854 }
931 855
932 // Set up specific unhandled exception handler.
933 const String& callback_name = String::Handle(
934 isolate, String::New(state->exception_callback_name()));
935 isolate->object_store()->
936 set_unhandled_exception_handler(callback_name);
937
938 Object& result = Object::Handle(); 856 Object& result = Object::Handle();
939 result = state->ResolveFunction(); 857 result = state->ResolveFunction();
940 bool is_spawn_uri = state->is_spawn_uri(); 858 bool is_spawn_uri = state->is_spawn_uri();
941 if (result.IsError()) { 859 if (result.IsError()) {
942 StoreError(isolate, result); 860 StoreError(isolate, result);
943 return false; 861 return false;
944 } 862 }
945 ASSERT(result.IsFunction()); 863 ASSERT(result.IsFunction());
946 Function& func = Function::Handle(isolate); 864 Function& func = Function::Handle(isolate);
947 func ^= result.raw(); 865 func ^= result.raw();
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
1544 const Function& func, 1462 const Function& func,
1545 const Instance& message, 1463 const Instance& message,
1546 bool paused) 1464 bool paused)
1547 : isolate_(NULL), 1465 : isolate_(NULL),
1548 parent_port_(parent_port), 1466 parent_port_(parent_port),
1549 script_url_(NULL), 1467 script_url_(NULL),
1550 package_root_(NULL), 1468 package_root_(NULL),
1551 library_url_(NULL), 1469 library_url_(NULL),
1552 class_name_(NULL), 1470 class_name_(NULL),
1553 function_name_(NULL), 1471 function_name_(NULL),
1554 exception_callback_name_(NULL),
1555 serialized_args_(NULL), 1472 serialized_args_(NULL),
1556 serialized_args_len_(0), 1473 serialized_args_len_(0),
1557 serialized_message_(NULL), 1474 serialized_message_(NULL),
1558 serialized_message_len_(0), 1475 serialized_message_len_(0),
1559 paused_(paused) { 1476 paused_(paused) {
1560 script_url_ = NULL; 1477 script_url_ = NULL;
1561 const Class& cls = Class::Handle(func.Owner()); 1478 const Class& cls = Class::Handle(func.Owner());
1562 const Library& lib = Library::Handle(cls.library()); 1479 const Library& lib = Library::Handle(cls.library());
1563 const String& lib_url = String::Handle(lib.url()); 1480 const String& lib_url = String::Handle(lib.url());
1564 library_url_ = strdup(lib_url.ToCString()); 1481 library_url_ = strdup(lib_url.ToCString());
1565 1482
1566 const String& func_name = String::Handle(func.name()); 1483 const String& func_name = String::Handle(func.name());
1567 function_name_ = strdup(func_name.ToCString()); 1484 function_name_ = strdup(func_name.ToCString());
1568 if (!cls.IsTopLevel()) { 1485 if (!cls.IsTopLevel()) {
1569 const String& class_name = String::Handle(cls.Name()); 1486 const String& class_name = String::Handle(cls.Name());
1570 class_name_ = strdup(class_name.ToCString()); 1487 class_name_ = strdup(class_name.ToCString());
1571 } 1488 }
1572 exception_callback_name_ = strdup("_unhandledExceptionCallback");
1573 SerializeObject(message, &serialized_message_, &serialized_message_len_); 1489 SerializeObject(message, &serialized_message_, &serialized_message_len_);
1574 } 1490 }
1575 1491
1576 1492
1577 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, 1493 IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port,
1578 const char* script_url, 1494 const char* script_url,
1579 const char* package_root, 1495 const char* package_root,
1580 const Instance& args, 1496 const Instance& args,
1581 const Instance& message, 1497 const Instance& message,
1582 bool paused) 1498 bool paused)
1583 : isolate_(NULL), 1499 : isolate_(NULL),
1584 parent_port_(parent_port), 1500 parent_port_(parent_port),
1585 package_root_(NULL), 1501 package_root_(NULL),
1586 library_url_(NULL), 1502 library_url_(NULL),
1587 class_name_(NULL), 1503 class_name_(NULL),
1588 function_name_(NULL), 1504 function_name_(NULL),
1589 exception_callback_name_(NULL),
1590 serialized_args_(NULL), 1505 serialized_args_(NULL),
1591 serialized_args_len_(0), 1506 serialized_args_len_(0),
1592 serialized_message_(NULL), 1507 serialized_message_(NULL),
1593 serialized_message_len_(0), 1508 serialized_message_len_(0),
1594 paused_(paused) { 1509 paused_(paused) {
1595 script_url_ = strdup(script_url); 1510 script_url_ = strdup(script_url);
1596 if (package_root != NULL) { 1511 if (package_root != NULL) {
1597 package_root_ = strdup(package_root); 1512 package_root_ = strdup(package_root);
1598 } 1513 }
1599 library_url_ = NULL; 1514 library_url_ = NULL;
1600 function_name_ = strdup("main"); 1515 function_name_ = strdup("main");
1601 exception_callback_name_ = strdup("_unhandledExceptionCallback");
1602 SerializeObject(args, &serialized_args_, &serialized_args_len_); 1516 SerializeObject(args, &serialized_args_, &serialized_args_len_);
1603 SerializeObject(message, &serialized_message_, &serialized_message_len_); 1517 SerializeObject(message, &serialized_message_, &serialized_message_len_);
1604 } 1518 }
1605 1519
1606 1520
1607 IsolateSpawnState::~IsolateSpawnState() { 1521 IsolateSpawnState::~IsolateSpawnState() {
1608 free(script_url_); 1522 free(script_url_);
1609 free(package_root_); 1523 free(package_root_);
1610 free(library_url_); 1524 free(library_url_);
1611 free(function_name_); 1525 free(function_name_);
1612 free(class_name_); 1526 free(class_name_);
1613 free(exception_callback_name_);
1614 free(serialized_args_); 1527 free(serialized_args_);
1615 free(serialized_message_); 1528 free(serialized_message_);
1616 } 1529 }
1617 1530
1618 1531
1619 RawObject* IsolateSpawnState::ResolveFunction() { 1532 RawObject* IsolateSpawnState::ResolveFunction() {
1620 // Resolve the library. 1533 // Resolve the library.
1621 Library& lib = Library::Handle(); 1534 Library& lib = Library::Handle();
1622 if (library_url()) { 1535 if (library_url()) {
1623 const String& lib_url = String::Handle(String::New(library_url())); 1536 const String& lib_url = String::Handle(String::New(library_url()));
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 serialized_message_, serialized_message_len_); 1592 serialized_message_, serialized_message_len_);
1680 } 1593 }
1681 1594
1682 1595
1683 void IsolateSpawnState::Cleanup() { 1596 void IsolateSpawnState::Cleanup() {
1684 SwitchIsolateScope switch_scope(I); 1597 SwitchIsolateScope switch_scope(I);
1685 Dart::ShutdownIsolate(); 1598 Dart::ShutdownIsolate();
1686 } 1599 }
1687 1600
1688 } // namespace dart 1601 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/isolate.h ('k') | runtime/vm/object_store.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698