| OLD | NEW |
| 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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 if (is_compacting) { | 330 if (is_compacting) { |
| 331 StackFrame::UncookFramesForThread(thread); | 331 StackFrame::UncookFramesForThread(thread); |
| 332 } | 332 } |
| 333 } | 333 } |
| 334 | 334 |
| 335 | 335 |
| 336 static int stack_trace_nesting_level = 0; | 336 static int stack_trace_nesting_level = 0; |
| 337 static StringStream* incomplete_message = NULL; | 337 static StringStream* incomplete_message = NULL; |
| 338 | 338 |
| 339 | 339 |
| 340 Handle<String> Top::StackTrace() { | 340 Handle<String> Top::StackTraceString() { |
| 341 if (stack_trace_nesting_level == 0) { | 341 if (stack_trace_nesting_level == 0) { |
| 342 stack_trace_nesting_level++; | 342 stack_trace_nesting_level++; |
| 343 HeapStringAllocator allocator; | 343 HeapStringAllocator allocator; |
| 344 StringStream::ClearMentionedObjectCache(); | 344 StringStream::ClearMentionedObjectCache(); |
| 345 StringStream accumulator(&allocator); | 345 StringStream accumulator(&allocator); |
| 346 incomplete_message = &accumulator; | 346 incomplete_message = &accumulator; |
| 347 PrintStack(&accumulator); | 347 PrintStack(&accumulator); |
| 348 Handle<String> stack_trace = accumulator.ToString(); | 348 Handle<String> stack_trace = accumulator.ToString(); |
| 349 incomplete_message = NULL; | 349 incomplete_message = NULL; |
| 350 stack_trace_nesting_level = 0; | 350 stack_trace_nesting_level = 0; |
| 351 return stack_trace; | 351 return stack_trace; |
| 352 } else if (stack_trace_nesting_level == 1) { | 352 } else if (stack_trace_nesting_level == 1) { |
| 353 stack_trace_nesting_level++; | 353 stack_trace_nesting_level++; |
| 354 OS::PrintError( | 354 OS::PrintError( |
| 355 "\n\nAttempt to print stack while printing stack (double fault)\n"); | 355 "\n\nAttempt to print stack while printing stack (double fault)\n"); |
| 356 OS::PrintError( | 356 OS::PrintError( |
| 357 "If you are lucky you may find a partial stack dump on stdout.\n\n"); | 357 "If you are lucky you may find a partial stack dump on stdout.\n\n"); |
| 358 incomplete_message->OutputToStdOut(); | 358 incomplete_message->OutputToStdOut(); |
| 359 return Factory::empty_symbol(); | 359 return Factory::empty_symbol(); |
| 360 } else { | 360 } else { |
| 361 OS::Abort(); | 361 OS::Abort(); |
| 362 // Unreachable | 362 // Unreachable |
| 363 return Factory::empty_symbol(); | 363 return Factory::empty_symbol(); |
| 364 } | 364 } |
| 365 } | 365 } |
| 366 | 366 |
| 367 | 367 |
| 368 Local<StackTrace> Top::CaptureCurrentStackTrace( |
| 369 int frame_limit, StackTrace::StackTraceOptions options) { |
| 370 v8::HandleScope scope; |
| 371 // Ensure no negative values. |
| 372 int limit = Max(frame_limit, 0); |
| 373 Handle<JSArray> stackTrace = Factory::NewJSArray(frame_limit); |
| 374 FixedArray* frames = FixedArray::cast(stackTrace->elements()); |
| 375 |
| 376 Handle<String> column_key = Factory::LookupAsciiSymbol("column"); |
| 377 Handle<String> line_key = Factory::LookupAsciiSymbol("lineNumber"); |
| 378 Handle<String> script_key = Factory::LookupAsciiSymbol("scriptName"); |
| 379 Handle<String> function_key = Factory::LookupAsciiSymbol("functionName"); |
| 380 Handle<String> eval_key = Factory::LookupAsciiSymbol("isEval"); |
| 381 Handle<String> constructor_key = Factory::LookupAsciiSymbol("isConstructor"); |
| 382 |
| 383 StackTraceFrameIterator it; |
| 384 int frames_seen = 0; |
| 385 while (!it.done() && (frames_seen < limit)) { |
| 386 // Create a JSObject to hold the information for the StackFrame. |
| 387 Handle<JSObject> stackFrame = Factory::NewJSObject(object_function()); |
| 388 |
| 389 JavaScriptFrame* frame = it.frame(); |
| 390 JSFunction* fun(JSFunction::cast(frame->function())); |
| 391 Script* script = Script::cast(fun->shared()->script()); |
| 392 |
| 393 if (options & StackTrace::kLineNumber) { |
| 394 int script_line_offset = script->line_offset()->value(); |
| 395 int position = frame->code()->SourcePosition(frame->pc()); |
| 396 int line_number = GetScriptLineNumber(Handle<Script>(script), position); |
| 397 |
| 398 if (options & StackTrace::kColumnOffset) { |
| 399 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends())); |
| 400 int start = (line_number == 0) ? |
| 401 0 : Smi::cast(line_ends->get(line_number - 1))->value() + 1; |
| 402 int column_offset = position - start; |
| 403 if (line_number == script_line_offset) { |
| 404 // For the case where the code is on the same line as the script tag. |
| 405 column_offset += script_line_offset; |
| 406 } |
| 407 SetProperty(stackFrame, column_key, |
| 408 Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE); |
| 409 } |
| 410 // Adjust the line_number by the offset in the parent resource. |
| 411 line_number += script_line_offset; |
| 412 SetProperty(stackFrame, line_key, |
| 413 Handle<Smi>(Smi::FromInt(line_number + 1)), NONE); |
| 414 } |
| 415 |
| 416 if (options & StackTrace::kScriptName) { |
| 417 Handle<Object> script_name(script->name()); |
| 418 SetProperty(stackFrame, script_key, script_name, NONE); |
| 419 } |
| 420 |
| 421 if (options & StackTrace::kFunctionName) { |
| 422 Handle<Object> fun_name(fun->shared()->name()); |
| 423 if (!fun_name->IsString()) { |
| 424 fun_name = Handle<Object>(fun->shared()->inferred_name()); |
| 425 } |
| 426 SetProperty(stackFrame, function_key, fun_name, NONE); |
| 427 } |
| 428 |
| 429 if (options & StackTrace::kIsEval) { |
| 430 int type = Smi::cast(script->compilation_type())->value(); |
| 431 Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ? |
| 432 Factory::true_value() : Factory::false_value(); |
| 433 SetProperty(stackFrame, eval_key, is_eval, NONE); |
| 434 } |
| 435 |
| 436 if (options & StackTrace::kIsConstructor) { |
| 437 Handle<Object> is_constructor = (frame->IsConstructor()) ? |
| 438 Factory::true_value() : Factory::false_value(); |
| 439 SetProperty(stackFrame, constructor_key, is_constructor, NONE); |
| 440 } |
| 441 |
| 442 frames->set(frames_seen, *stackFrame); |
| 443 frames_seen++; |
| 444 it.Advance(); |
| 445 } |
| 446 |
| 447 stackTrace->set_length(Smi::FromInt(frames_seen)); |
| 448 return scope.Close(Utils::StackTraceToLocal(stackTrace)); |
| 449 } |
| 450 |
| 451 |
| 368 void Top::PrintStack() { | 452 void Top::PrintStack() { |
| 369 if (stack_trace_nesting_level == 0) { | 453 if (stack_trace_nesting_level == 0) { |
| 370 stack_trace_nesting_level++; | 454 stack_trace_nesting_level++; |
| 371 | 455 |
| 372 StringAllocator* allocator; | 456 StringAllocator* allocator; |
| 373 if (preallocated_message_space == NULL) { | 457 if (preallocated_message_space == NULL) { |
| 374 allocator = new HeapStringAllocator(); | 458 allocator = new HeapStringAllocator(); |
| 375 } else { | 459 } else { |
| 376 allocator = preallocated_message_space; | 460 allocator = preallocated_message_space; |
| 377 } | 461 } |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 if (location == NULL) { | 863 if (location == NULL) { |
| 780 // If no location was specified we use a computed one instead | 864 // If no location was specified we use a computed one instead |
| 781 ComputeLocation(&potential_computed_location); | 865 ComputeLocation(&potential_computed_location); |
| 782 location = &potential_computed_location; | 866 location = &potential_computed_location; |
| 783 } | 867 } |
| 784 if (!Bootstrapper::IsActive()) { | 868 if (!Bootstrapper::IsActive()) { |
| 785 // It's not safe to try to make message objects or collect stack | 869 // It's not safe to try to make message objects or collect stack |
| 786 // traces while the bootstrapper is active since the infrastructure | 870 // traces while the bootstrapper is active since the infrastructure |
| 787 // may not have been properly initialized. | 871 // may not have been properly initialized. |
| 788 Handle<String> stack_trace; | 872 Handle<String> stack_trace; |
| 789 if (FLAG_trace_exception) stack_trace = StackTrace(); | 873 if (FLAG_trace_exception) stack_trace = StackTraceString(); |
| 790 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", | 874 message_obj = MessageHandler::MakeMessageObject("uncaught_exception", |
| 791 location, HandleVector<Object>(&exception_handle, 1), stack_trace); | 875 location, HandleVector<Object>(&exception_handle, 1), stack_trace); |
| 792 } | 876 } |
| 793 } | 877 } |
| 794 | 878 |
| 795 // Save the message for reporting if the the exception remains uncaught. | 879 // Save the message for reporting if the the exception remains uncaught. |
| 796 thread_local_.has_pending_message_ = report_exception; | 880 thread_local_.has_pending_message_ = report_exception; |
| 797 thread_local_.pending_message_ = message; | 881 thread_local_.pending_message_ = message; |
| 798 if (!message_obj.is_null()) { | 882 if (!message_obj.is_null()) { |
| 799 thread_local_.pending_message_obj_ = *message_obj; | 883 thread_local_.pending_message_obj_ = *message_obj; |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 Top::break_access_->Lock(); | 1061 Top::break_access_->Lock(); |
| 978 } | 1062 } |
| 979 | 1063 |
| 980 | 1064 |
| 981 ExecutionAccess::~ExecutionAccess() { | 1065 ExecutionAccess::~ExecutionAccess() { |
| 982 Top::break_access_->Unlock(); | 1066 Top::break_access_->Unlock(); |
| 983 } | 1067 } |
| 984 | 1068 |
| 985 | 1069 |
| 986 } } // namespace v8::internal | 1070 } } // namespace v8::internal |
| OLD | NEW |