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

Side by Side Diff: src/isolate.cc

Issue 9310122: When rethrowing an exception, print the stack trace of its original site instead of rethrow site. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: . Created 8 years, 10 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 incomplete_message_->OutputToStdOut(); 535 incomplete_message_->OutputToStdOut();
536 return factory()->empty_symbol(); 536 return factory()->empty_symbol();
537 } else { 537 } else {
538 OS::Abort(); 538 OS::Abort();
539 // Unreachable 539 // Unreachable
540 return factory()->empty_symbol(); 540 return factory()->empty_symbol();
541 } 541 }
542 } 542 }
543 543
544 544
545 void Isolate::CaptureAndSetCurrentStackTraceFor(Handle<JSObject> error_object) {
546 if (capture_stack_trace_for_uncaught_exceptions_) {
547 // Capture stack trace for a detailed exception message.
548 Handle<String> key(heap()->hidden_stack_trace_symbol());
Vyacheslav Egorov (Chromium) 2012/02/07 09:17:37 you can use factory()->hidden_stack_trace_symbol()
549 Handle<JSArray> stack_trace = CaptureCurrentStackTrace(
550 stack_trace_for_uncaught_exceptions_frame_limit_,
551 stack_trace_for_uncaught_exceptions_options_);
552 JSObject::SetHiddenProperty(error_object, key, stack_trace);
553 }
554 }
555
556
545 Handle<JSArray> Isolate::CaptureCurrentStackTrace( 557 Handle<JSArray> Isolate::CaptureCurrentStackTrace(
546 int frame_limit, StackTrace::StackTraceOptions options) { 558 int frame_limit, StackTrace::StackTraceOptions options) {
547 // Ensure no negative values. 559 // Ensure no negative values.
548 int limit = Max(frame_limit, 0); 560 int limit = Max(frame_limit, 0);
549 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit); 561 Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
550 562
551 Handle<String> column_key = factory()->LookupAsciiSymbol("column"); 563 Handle<String> column_key = factory()->LookupAsciiSymbol("column");
552 Handle<String> line_key = factory()->LookupAsciiSymbol("lineNumber"); 564 Handle<String> line_key = factory()->LookupAsciiSymbol("lineNumber");
553 Handle<String> script_key = factory()->LookupAsciiSymbol("scriptName"); 565 Handle<String> script_key = factory()->LookupAsciiSymbol("scriptName");
554 Handle<String> name_or_source_url_key = 566 Handle<String> name_or_source_url_key =
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 if (*can_be_caught_externally) { 1042 if (*can_be_caught_externally) {
1031 // Only report the exception if the external handler is verbose. 1043 // Only report the exception if the external handler is verbose.
1032 return try_catch_handler()->is_verbose_; 1044 return try_catch_handler()->is_verbose_;
1033 } else { 1045 } else {
1034 // Report the exception if it isn't caught by JavaScript code. 1046 // Report the exception if it isn't caught by JavaScript code.
1035 return handler == NULL; 1047 return handler == NULL;
1036 } 1048 }
1037 } 1049 }
1038 1050
1039 1051
1040 void Isolate::DoThrow(MaybeObject* exception, MessageLocation* location) { 1052 bool Isolate::IsErrorObject(Handle<Object> obj) {
1053 if (!obj->IsJSObject()) return false;
1054
1055 String* error_key = *(factory()->LookupAsciiSymbol("$Error"));
1056 Object* error_constructor =
1057 js_builtins_object()->GetPropertyNoExceptionThrown(error_key);
1058
1059 for (Object* prototype = *obj; !prototype->IsNull();
1060 prototype = prototype->GetPrototype()) {
1061 if (!prototype->IsJSObject()) return false;
1062 if (JSObject::cast(prototype)->map()->constructor() == error_constructor) {
1063 return true;
1064 }
1065 }
1066 return false;
1067 }
1068
1069
1070 void Isolate::DoThrow(Object* exception, MessageLocation* location) {
1041 ASSERT(!has_pending_exception()); 1071 ASSERT(!has_pending_exception());
1042 1072
1043 HandleScope scope; 1073 HandleScope scope;
1044 Object* exception_object = Smi::FromInt(0); 1074 Handle<Object> exception_handle(exception);
1045 bool is_object = exception->ToObject(&exception_object);
1046 Handle<Object> exception_handle(exception_object);
1047 1075
1048 // Determine reporting and whether the exception is caught externally. 1076 // Determine reporting and whether the exception is caught externally.
1049 bool catchable_by_javascript = is_catchable_by_javascript(exception); 1077 bool catchable_by_javascript = is_catchable_by_javascript(exception);
1050 // Only real objects can be caught by JS.
1051 ASSERT(!catchable_by_javascript || is_object);
1052 bool can_be_caught_externally = false; 1078 bool can_be_caught_externally = false;
1053 bool should_report_exception = 1079 bool should_report_exception =
1054 ShouldReportException(&can_be_caught_externally, catchable_by_javascript); 1080 ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
1055 bool report_exception = catchable_by_javascript && should_report_exception; 1081 bool report_exception = catchable_by_javascript && should_report_exception;
1082 bool try_catch_needs_message =
1083 can_be_caught_externally && try_catch_handler()->capture_message_;
1084 bool bootstrapping = bootstrapper()->IsActive();
1056 1085
1057 #ifdef ENABLE_DEBUGGER_SUPPORT 1086 #ifdef ENABLE_DEBUGGER_SUPPORT
1058 // Notify debugger of exception. 1087 // Notify debugger of exception.
1059 if (catchable_by_javascript) { 1088 if (catchable_by_javascript) {
1060 debugger_->OnException(exception_handle, report_exception); 1089 debugger_->OnException(exception_handle, report_exception);
1061 } 1090 }
1062 #endif 1091 #endif
1063 1092
1064 // Generate the message. 1093 // Generate the message if required.
1065 Handle<Object> message_obj;
1066 MessageLocation potential_computed_location;
1067 bool try_catch_needs_message =
1068 can_be_caught_externally &&
1069 try_catch_handler()->capture_message_;
1070 if (report_exception || try_catch_needs_message) { 1094 if (report_exception || try_catch_needs_message) {
1095 MessageLocation potential_computed_location;
1071 if (location == NULL) { 1096 if (location == NULL) {
1072 // If no location was specified we use a computed one instead 1097 // If no location was specified we use a computed one instead.
1073 ComputeLocation(&potential_computed_location); 1098 ComputeLocation(&potential_computed_location);
1074 location = &potential_computed_location; 1099 location = &potential_computed_location;
1075 } 1100 }
1076 if (!bootstrapper()->IsActive()) { 1101 // It's not safe to try to make message objects or collect stack traces
1077 // It's not safe to try to make message objects or collect stack 1102 // while the bootstrapper is active since the infrastructure may not have
1078 // traces while the bootstrapper is active since the infrastructure 1103 // been properly initialized.
1079 // may not have been properly initialized. 1104 if (!bootstrapping) {
1080 Handle<String> stack_trace; 1105 Handle<String> stack_trace;
1081 if (FLAG_trace_exception) stack_trace = StackTraceString(); 1106 if (FLAG_trace_exception) stack_trace = StackTraceString();
1082 Handle<JSArray> stack_trace_object; 1107 Handle<JSArray> stack_trace_object;
1083 if (report_exception && capture_stack_trace_for_uncaught_exceptions_) { 1108 if (capture_stack_trace_for_uncaught_exceptions_) {
1109 if (IsErrorObject(exception_handle)) {
1110 // We fetch the stack trace that corresponds to this error object.
1111 String* key = heap()->hidden_stack_trace_symbol();
1112 Object* stack_property =
1113 JSObject::cast(*exception_handle)->GetHiddenProperty(key);
1114 // Property lookup may have failed. In this case it's probably not
1115 // a valid Error object.
1116 if (stack_property->IsJSArray()) {
1117 stack_trace_object = Handle<JSArray>(JSArray::cast(stack_property));
1118 }
1119 }
1120 if (stack_trace_object.is_null()) {
1121 // Not an error object, we capture at throw site.
1084 stack_trace_object = CaptureCurrentStackTrace( 1122 stack_trace_object = CaptureCurrentStackTrace(
1085 stack_trace_for_uncaught_exceptions_frame_limit_, 1123 stack_trace_for_uncaught_exceptions_frame_limit_,
1086 stack_trace_for_uncaught_exceptions_options_); 1124 stack_trace_for_uncaught_exceptions_options_);
1125 }
1087 } 1126 }
1088 ASSERT(is_object); // Can't use the handle unless there's a real object. 1127 Handle<Object> message_obj = MessageHandler::MakeMessageObject(
1089 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", 1128 "uncaught_exception",
1090 location, HandleVector<Object>(&exception_handle, 1), stack_trace, 1129 location,
1130 HandleVector<Object>(&exception_handle, 1),
1131 stack_trace,
1091 stack_trace_object); 1132 stack_trace_object);
1133 thread_local_top()->pending_message_obj_ = *message_obj;
1134 if (location != NULL) {
1135 thread_local_top()->pending_message_script_ = *location->script();
1136 thread_local_top()->pending_message_start_pos_ = location->start_pos();
1137 thread_local_top()->pending_message_end_pos_ = location->end_pos();
1138 }
1092 } else if (location != NULL && !location->script().is_null()) { 1139 } else if (location != NULL && !location->script().is_null()) {
1093 // We are bootstrapping and caught an error where the location is set 1140 // We are bootstrapping and caught an error where the location is set
1094 // and we have a script for the location. 1141 // and we have a script for the location.
1095 // In this case we could have an extension (or an internal error 1142 // In this case we could have an extension (or an internal error
1096 // somewhere) and we print out the line number at which the error occured 1143 // somewhere) and we print out the line number at which the error occured
1097 // to the console for easier debugging. 1144 // to the console for easier debugging.
1098 int line_number = GetScriptLineNumberSafe(location->script(), 1145 int line_number = GetScriptLineNumberSafe(location->script(),
1099 location->start_pos()); 1146 location->start_pos());
1100 OS::PrintError("Extension or internal compilation error at line %d.\n", 1147 OS::PrintError("Extension or internal compilation error at line %d.\n",
1101 line_number); 1148 line_number);
1102 } 1149 }
1103 } 1150 }
1104 1151
1105 // Save the message for reporting if the the exception remains uncaught. 1152 // Save the message for reporting if the the exception remains uncaught.
1106 thread_local_top()->has_pending_message_ = report_exception; 1153 thread_local_top()->has_pending_message_ = report_exception;
1107 if (!message_obj.is_null()) {
1108 thread_local_top()->pending_message_obj_ = *message_obj;
1109 if (location != NULL) {
1110 thread_local_top()->pending_message_script_ = *location->script();
1111 thread_local_top()->pending_message_start_pos_ = location->start_pos();
1112 thread_local_top()->pending_message_end_pos_ = location->end_pos();
1113 }
1114 }
1115 1154
1116 // Do not forget to clean catcher_ if currently thrown exception cannot 1155 // Do not forget to clean catcher_ if currently thrown exception cannot
1117 // be caught. If necessary, ReThrow will update the catcher. 1156 // be caught. If necessary, ReThrow will update the catcher.
1118 thread_local_top()->catcher_ = can_be_caught_externally ? 1157 thread_local_top()->catcher_ = can_be_caught_externally ?
1119 try_catch_handler() : NULL; 1158 try_catch_handler() : NULL;
1120 1159
1121 // NOTE: Notifying the debugger or generating the message 1160 set_pending_exception(*exception_handle);
1122 // may have caused new exceptions. For now, we just ignore
1123 // that and set the pending exception to the original one.
1124 if (is_object) {
1125 set_pending_exception(*exception_handle);
1126 } else {
1127 // Failures are not on the heap so they neither need nor work with handles.
1128 ASSERT(exception_handle->IsFailure());
1129 set_pending_exception(exception);
1130 }
1131 } 1161 }
1132 1162
1133 1163
1134 bool Isolate::IsExternallyCaught() { 1164 bool Isolate::IsExternallyCaught() {
1135 ASSERT(has_pending_exception()); 1165 ASSERT(has_pending_exception());
1136 1166
1137 if ((thread_local_top()->catcher_ == NULL) || 1167 if ((thread_local_top()->catcher_ == NULL) ||
1138 (try_catch_handler() != thread_local_top()->catcher_)) { 1168 (try_catch_handler() != thread_local_top()->catcher_)) {
1139 // When throwing the exception, we found no v8::TryCatch 1169 // When throwing the exception, we found no v8::TryCatch
1140 // which should care about this exception. 1170 // which should care about this exception.
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
1920 1950
1921 #ifdef DEBUG 1951 #ifdef DEBUG
1922 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ 1952 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \
1923 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); 1953 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
1924 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) 1954 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
1925 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) 1955 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
1926 #undef ISOLATE_FIELD_OFFSET 1956 #undef ISOLATE_FIELD_OFFSET
1927 #endif 1957 #endif
1928 1958
1929 } } // namespace v8::internal 1959 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/isolate.h ('k') | src/messages.js » ('j') | test/cctest/test-api.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698