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

Side by Side Diff: src/top.cc

Issue 2028001: Adds C++ API for retrieving a stack trace without running JavaScript... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 7 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 | « src/top.h ('k') | test/cctest/test-api.cc » ('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 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
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
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
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
OLDNEW
« no previous file with comments | « src/top.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698