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

Unified Diff: src/top.cc

Issue 1694011: 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, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/top.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/top.cc
===================================================================
--- src/top.cc (revision 4556)
+++ src/top.cc (working copy)
@@ -337,7 +337,7 @@
static StringStream* incomplete_message = NULL;
-Handle<String> Top::StackTrace() {
+Handle<String> Top::StackTraceString() {
if (stack_trace_nesting_level == 0) {
stack_trace_nesting_level++;
HeapStringAllocator allocator;
@@ -365,6 +365,90 @@
}
+Local<StackTrace> Top::CaptureCurrentStackTrace(
+ int frame_limit, StackTrace::StackTraceOptions options) {
+ v8::HandleScope scope;
+ // Ensure no negative values.
+ int limit = Max(frame_limit, 0);
+ Handle<JSArray> stackTrace = Factory::NewJSArray(frame_limit);
+ FixedArray* frames = FixedArray::cast(stackTrace->elements());
+
+ Handle<String> column_key = Factory::LookupAsciiSymbol("column");
+ Handle<String> line_key = Factory::LookupAsciiSymbol("lineNumber");
+ Handle<String> script_key = Factory::LookupAsciiSymbol("scriptName");
+ Handle<String> function_key = Factory::LookupAsciiSymbol("functionName");
+ Handle<String> eval_key = Factory::LookupAsciiSymbol("isEval");
+ Handle<String> constructor_key = Factory::LookupAsciiSymbol("isConstructor");
+
+ StackTraceFrameIterator it;
+ int frames_seen = 0;
+ while (!it.done() && (frames_seen < limit)) {
+ // Create a JSObject to hold the information for the StackFrame.
+ Handle<JSObject> stackFrame = Factory::NewJSObject(object_function());
+
+ JavaScriptFrame* frame = it.frame();
+ JSFunction* fun(JSFunction::cast(frame->function()));
+ Script* script = Script::cast(fun->shared()->script());
+
+ if (options & StackTrace::kLineNumber) {
+ int script_line_offset = script->line_offset()->value();
+ int position = frame->code()->SourcePosition(frame->pc());
+ int line_number = GetScriptLineNumber(Handle<Script>(script), position);
+
+ if (options & StackTrace::kColumnOffset) {
+ Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
+ int start = (line_number == 0) ?
+ 0 : Smi::cast(line_ends->get(line_number - 1))->value() + 1;
+ int column_offset = position - start;
+ if (line_number == script_line_offset) {
+ // For the case where the code is on the same line as the script tag.
+ column_offset += script_line_offset;
+ }
+ SetProperty(stackFrame, column_key,
+ Handle<Smi>(Smi::FromInt(column_offset + 1)), NONE);
+ }
+ // Adjust the line_number by the offset in the parent resource.
+ line_number += script_line_offset;
+ SetProperty(stackFrame, line_key,
+ Handle<Smi>(Smi::FromInt(line_number + 1)), NONE);
+ }
+
+ if (options & StackTrace::kScriptName) {
+ Handle<Object> script_name(script->name());
+ SetProperty(stackFrame, script_key, script_name, NONE);
+ }
+
+ if (options & StackTrace::kFunctionName) {
+ Handle<Object> fun_name(fun->shared()->name());
+ if (!fun_name->IsString()) {
+ fun_name = Handle<Object>(fun->shared()->inferred_name());
+ }
+ SetProperty(stackFrame, function_key, fun_name, NONE);
+ }
+
+ if (options & StackTrace::kIsEval) {
+ int type = Smi::cast(script->compilation_type())->value();
+ Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
+ Factory::true_value() : Factory::false_value();
+ SetProperty(stackFrame, eval_key, is_eval, NONE);
+ }
+
+ if (options & StackTrace::kIsConstructor) {
+ Handle<Object> is_constructor = (frame->IsConstructor()) ?
+ Factory::true_value() : Factory::false_value();
+ SetProperty(stackFrame, constructor_key, is_constructor, NONE);
+ }
+
+ frames->set(frames_seen, *stackFrame);
+ frames_seen++;
+ it.Advance();
+ }
+
+ stackTrace->set_length(Smi::FromInt(frames_seen));
+ return scope.Close(Utils::StackTraceToLocal(stackTrace));
+}
+
+
void Top::PrintStack() {
if (stack_trace_nesting_level == 0) {
stack_trace_nesting_level++;
@@ -786,7 +870,7 @@
// traces while the bootstrapper is active since the infrastructure
// may not have been properly initialized.
Handle<String> stack_trace;
- if (FLAG_trace_exception) stack_trace = StackTrace();
+ if (FLAG_trace_exception) stack_trace = StackTraceString();
message_obj = MessageHandler::MakeMessageObject("uncaught_exception",
location, HandleVector<Object>(&exception_handle, 1), stack_trace);
}
« 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