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

Side by Side Diff: src/top.cc

Issue 12901: Reporting uncaught errors at the boundary between C++ and JS instead of tryin... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years 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
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage); 59 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage);
60 Iterate(v, thread); 60 Iterate(v, thread);
61 return thread_storage + sizeof(ThreadLocalTop); 61 return thread_storage + sizeof(ThreadLocalTop);
62 } 62 }
63 63
64 64
65 #define VISIT(field) v->VisitPointer(reinterpret_cast<Object**>(&(field))); 65 #define VISIT(field) v->VisitPointer(reinterpret_cast<Object**>(&(field)));
66 66
67 void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) { 67 void Top::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
68 v->VisitPointer(&(thread->pending_exception_)); 68 v->VisitPointer(&(thread->pending_exception_));
69 v->VisitPointer(&(thread->pending_message_obj_));
70 v->VisitPointer(bit_cast<Object**, Script**>(&(thread->pending_message_script_ )));
69 v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_))); 71 v->VisitPointer(bit_cast<Object**, Context**>(&(thread->context_)));
70 v->VisitPointer(&(thread->scheduled_exception_)); 72 v->VisitPointer(&(thread->scheduled_exception_));
71 73
72 for (v8::TryCatch* block = thread->try_catch_handler_; 74 for (v8::TryCatch* block = thread->try_catch_handler_;
73 block != NULL; 75 block != NULL;
74 block = block->next_) { 76 block = block->next_) {
75 v->VisitPointer(bit_cast<Object**, void**>(&(block->exception_))); 77 v->VisitPointer(bit_cast<Object**, void**>(&(block->exception_)));
76 v->VisitPointer(bit_cast<Object**, void**>(&(block->message_))); 78 v->VisitPointer(bit_cast<Object**, void**>(&(block->message_)));
77 } 79 }
78 80
(...skipping 13 matching lines...) Expand all
92 94
93 void Top::InitializeThreadLocal() { 95 void Top::InitializeThreadLocal() {
94 thread_local_.c_entry_fp_ = 0; 96 thread_local_.c_entry_fp_ = 0;
95 thread_local_.handler_ = 0; 97 thread_local_.handler_ = 0;
96 thread_local_.stack_is_cooked_ = false; 98 thread_local_.stack_is_cooked_ = false;
97 thread_local_.try_catch_handler_ = NULL; 99 thread_local_.try_catch_handler_ = NULL;
98 thread_local_.context_ = NULL; 100 thread_local_.context_ = NULL;
99 thread_local_.external_caught_exception_ = false; 101 thread_local_.external_caught_exception_ = false;
100 thread_local_.failed_access_check_callback_ = NULL; 102 thread_local_.failed_access_check_callback_ = NULL;
101 clear_pending_exception(); 103 clear_pending_exception();
104 clear_pending_message();
102 clear_scheduled_exception(); 105 clear_scheduled_exception();
103 thread_local_.save_context_ = NULL; 106 thread_local_.save_context_ = NULL;
104 thread_local_.catcher_ = NULL; 107 thread_local_.catcher_ = NULL;
105 } 108 }
106 109
107 110
108 // Create a dummy thread that will wait forever on a semaphore. The only 111 // Create a dummy thread that will wait forever on a semaphore. The only
109 // purpose for this thread is to have some stack area to save essential data 112 // purpose for this thread is to have some stack area to save essential data
110 // into for use by a stacks only core dump (aka minidump). 113 // into for use by a stacks only core dump (aka minidump).
111 class PreallocatedMemoryThread: public Thread { 114 class PreallocatedMemoryThread: public Thread {
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 MessageHandler::MakeMessageObject("uncaught_exception", 732 MessageHandler::MakeMessageObject("uncaught_exception",
730 location, 733 location,
731 HandleVector<Object>(&exception, 1), 734 HandleVector<Object>(&exception, 1),
732 stack_trace); 735 stack_trace);
733 736
734 // Report the uncaught exception. 737 // Report the uncaught exception.
735 MessageHandler::ReportMessage(location, message); 738 MessageHandler::ReportMessage(location, message);
736 } 739 }
737 740
738 741
739 bool Top::ShouldReportException(bool* is_caught_externally) { 742 bool Top::IsUncaughtException(bool* is_caught_externally) {
Søren Thygesen Gjesse 2008/12/04 07:53:53 This function does not only check whether the exce
olehougaard 2008/12/04 08:44:35 Reverting to the original name.
740 StackHandler* handler = 743 StackHandler* handler =
741 StackHandler::FromAddress(Top::handler(Top::GetCurrentThread())); 744 StackHandler::FromAddress(Top::handler(Top::GetCurrentThread()));
742 745
743 // Determine if we have an external exception handler and get the 746 // Determine if we have an external exception handler and get the
744 // address of the external handler so we can compare the address to 747 // address of the external handler so we can compare the address to
745 // determine which one is closer to the top of the stack. 748 // determine which one is closer to the top of the stack.
746 bool has_external_handler = (thread_local_.try_catch_handler_ != NULL); 749 bool has_external_handler = (thread_local_.try_catch_handler_ != NULL);
747 v8::TryCatch* try_catch = thread_local_.try_catch_handler_; 750 v8::TryCatch* try_catch = thread_local_.try_catch_handler_;
748 751
749 // NOTE: The stack is assumed to grown towards lower addresses. If 752 // NOTE: The stack is assumed to grown towards lower addresses. If
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 void Top::DoThrow(Object* exception, 787 void Top::DoThrow(Object* exception,
785 MessageLocation* location, 788 MessageLocation* location,
786 const char* message) { 789 const char* message) {
787 ASSERT(!has_pending_exception()); 790 ASSERT(!has_pending_exception());
788 791
789 HandleScope scope; 792 HandleScope scope;
790 Handle<Object> exception_handle(exception); 793 Handle<Object> exception_handle(exception);
791 794
792 // Determine reporting and whether the exception is caught externally. 795 // Determine reporting and whether the exception is caught externally.
793 bool is_caught_externally = false; 796 bool is_caught_externally = false;
794 bool report_exception = (exception != Failure::OutOfMemoryException()) && 797 bool is_out_of_memory = exception == Failure::OutOfMemoryException();
795 ShouldReportException(&is_caught_externally); 798 bool is_uncaught_exception = IsUncaughtException(&is_caught_externally);
799 bool report_exception = !is_out_of_memory && is_uncaught_exception;
800
801
802 // Notify debugger of exception.
803 Debugger::OnException(exception_handle, report_exception);
796 804
797 // Generate the message. 805 // Generate the message.
798 Handle<Object> message_obj; 806 Handle<Object> message_obj;
799 MessageLocation potential_computed_location; 807 MessageLocation potential_computed_location;
800 bool try_catch_needs_message = 808 bool try_catch_needs_message =
801 is_caught_externally && 809 is_caught_externally &&
802 thread_local_.try_catch_handler_->capture_message_; 810 thread_local_.try_catch_handler_->capture_message_;
803 if (report_exception || try_catch_needs_message) { 811 if (report_exception || try_catch_needs_message) {
804 if (location == NULL) { 812 if (location == NULL) {
805 // If no location was specified we use a computed one instead 813 // If no location was specified we use a computed one instead
806 ComputeLocation(&potential_computed_location); 814 ComputeLocation(&potential_computed_location);
807 location = &potential_computed_location; 815 location = &potential_computed_location;
808 } 816 }
809 Handle<String> stack_trace; 817 Handle<String> stack_trace;
810 if (FLAG_trace_exception) stack_trace = StackTrace(); 818 if (FLAG_trace_exception) stack_trace = StackTrace();
811 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", 819 message_obj = MessageHandler::MakeMessageObject("uncaught_exception",
812 location, HandleVector<Object>(&exception_handle, 1), stack_trace); 820 location, HandleVector<Object>(&exception_handle, 1), stack_trace);
813 } 821 }
814 822
815 // If the exception is caught externally, we store it in the 823 // Save the message for reporting if the the exception remains uncaught.
816 // try/catch handler. The C code can find it later and process it if 824 thread_local_.pending_message_ = message;
817 // necessary. 825 if (!message_obj.is_null()) {
818 thread_local_.catcher_ = NULL; 826 thread_local_.pending_message_obj_ = *message_obj;
819 if (is_caught_externally) { 827 if (location != NULL) {
820 thread_local_.catcher_ = thread_local_.try_catch_handler_; 828 thread_local_.pending_message_script_ = *location->script();
821 thread_local_.try_catch_handler_->exception_ = 829 thread_local_.pending_message_start_pos_ = location->start_pos();
822 reinterpret_cast<void*>(*exception_handle); 830 thread_local_.pending_message_end_pos_ = location->end_pos();
823 if (!message_obj.is_null()) {
824 thread_local_.try_catch_handler_->message_ =
825 reinterpret_cast<void*>(*message_obj);
826 } 831 }
827 } 832 }
828 833
829 // Notify debugger of exception. 834 if (is_caught_externally) {
830 Debugger::OnException(exception_handle, report_exception); 835 thread_local_.catcher_ = thread_local_.try_catch_handler_;
831
832 if (report_exception) {
833 if (message != NULL) {
834 MessageHandler::ReportMessage(message);
835 } else if (!message_obj.is_null()) {
836 MessageHandler::ReportMessage(location, message_obj);
837 }
838 } 836 }
839 837
840 // NOTE: Notifying the debugger or reporting the exception may have caused 838 // NOTE: Notifying the debugger may have caused new exceptions.
Søren Thygesen Gjesse 2008/12/04 07:53:53 Generating the message without reporting it can al
olehougaard 2008/12/04 08:44:35 Updated the comment.
841 // new exceptions. For now, we just ignore that and set the pending exception 839 // For now, we just ignore that and set the pending exception
842 // to the original one. 840 // to the original one.
843 set_pending_exception(*exception_handle); 841 set_pending_exception(*exception_handle);
844 } 842 }
845 843
846 844
845 void Top::ReportPendingMessages() {
846 ASSERT(has_pending_exception());
847 setup_external_caught();
848 // If the pending exception is OutOfMemoryException set out_of_memory in
849 // the global context. Note: We have to mark the global context here
850 // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to
851 // set it.
852 HandleScope scope;
853 if (thread_local_.pending_exception_ == Failure::OutOfMemoryException()) {
854 context()->mark_out_of_memory();
855 } else {
856 Handle<Object> exception(pending_exception());
857 if (thread_local_.external_caught_exception_) {
858 thread_local_.try_catch_handler_->exception_
859 = thread_local_.pending_exception_;
Mads Ager (chromium) 2008/12/03 15:44:48 We normally have the '=' on the previous line.
olehougaard 2008/12/04 08:44:35 Fixed.
860 if (!thread_local_.pending_message_obj_->IsTheHole()) {
861 try_catch_handler()->message_ = thread_local_.pending_message_obj_;
862 }
863 } else if (thread_local_.pending_message_ != NULL) {
864 MessageHandler::ReportMessage(thread_local_.pending_message_);
865 } else if (!thread_local_.pending_message_obj_->IsTheHole()) {
866 Handle<Object> message_obj(thread_local_.pending_message_obj_);
867 if (thread_local_.pending_message_script_ != NULL) {
868 Handle<Script> script(thread_local_.pending_message_script_);
869 int start_pos = thread_local_.pending_message_start_pos_;
870 int end_pos = thread_local_.pending_message_end_pos_;
871 MessageLocation location(script, start_pos, end_pos);
872 MessageHandler::ReportMessage(&location, message_obj);
873 } else {
874 MessageHandler::ReportMessage(NULL, message_obj);
875 }
876 }
877 set_pending_exception(*exception);
878 }
879 clear_pending_message();
880 }
881
882
847 void Top::TraceException(bool flag) { 883 void Top::TraceException(bool flag) {
848 FLAG_trace_exception = flag; 884 FLAG_trace_exception = flag;
849 } 885 }
850 886
851 887
852 bool Top::optional_reschedule_exception(bool is_bottom_call) { 888 bool Top::optional_reschedule_exception(bool is_bottom_call) {
853 if (!is_out_of_memory() && 889 if (!is_out_of_memory() &&
854 (thread_local_.external_caught_exception_ || is_bottom_call)) { 890 (thread_local_.external_caught_exception_ || is_bottom_call)) {
855 thread_local_.external_caught_exception_ = false; 891 thread_local_.external_caught_exception_ = false;
856 clear_pending_exception(); 892 clear_pending_exception();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 Top::break_access_->Lock(); 955 Top::break_access_->Lock();
920 } 956 }
921 957
922 958
923 ExecutionAccess::~ExecutionAccess() { 959 ExecutionAccess::~ExecutionAccess() {
924 Top::break_access_->Unlock(); 960 Top::break_access_->Unlock();
925 } 961 }
926 962
927 963
928 } } // namespace v8::internal 964 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698