Project: v8 Issues People Development process History Sign in
New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Issue 2169 can't get function arguments in stack trace from user scripts
Starred by 13 users Reported by char...@isomorphic.com, Jun 8 2012 Back to list
Status: WorkingAsIntended
Owner: ----
Closed: Apr 2015
Cc:
HW: ----
OS: ----
Priority: ----
Type: FeatureRequest



Sign in to add a comment
Error.prepareStackTrace() allows user scripts to programmatically put together a stack trace.

http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi

However it's not possible to get the arguments passed to each function in the stack, and this would be extremely useful.  Although CallSite.getFunction() allows access to function.arguments, there are two problems:

1. this would only work for non-recursive functions, since if the function appears more than once in the stack, it's "arguments" property will only have the most recent arguments.  This implies an API to get arguments is needed directly on CallSite.

2. Sample code below demonstrates that even if you use CallSite.getFunction(), function.arguments will not be present if you examine the CallSite objects in a catch block

In the sample code below, the trace alert()d with prefix "trace from before crash" can get arguments for all functions in the stack, the trace alert()d with prefix "trace from catch()" can only get them for functions that are still on the stack at the time the catch() block executes. A third trace is captured inside prepareStackTrace() just in case - this also cannot get arguments.

Error.prepareStackTrace = function(error, stack) {
    window.traceInsidePrepare = getTrace({ stack : stack }); 
    return stack;
};

var someObj = {
    someMethod : function () { 
        alert("trace from before crash: " + getTrace(new Error())); 
        crash();
    }
}
function bar(barArg) { someObj.someMethod(); };
function foo(fooArg) { bar("barArgString"); };

function getTrace(e) {
    var stack = e.stack;
    var trace = "";
    for (var i = 0; i < stack.length; i++) {
        var frame = stack[i],
            func = frame.getFunction();
        
        trace += "\r" + frame.getThis() + "." + frame.getFunctionName() +
                "\r    function first arg: " + (func.arguments != null ? func.arguments[0] : "<missing>");
    }
    return trace;
}

try {
    foo("fooArgString");
} catch (e) {
    alert("trace from catch(): " + getTrace(e));
    alert("trace inside prepare: " + window.traceInsidePrepare);
}

 
Labels: Type-FeatureRequest
I tried playing with this a little.

Part of the problem is that the custom stack trace formatter (Error.prepareStackTrace) runs lazily, only when the .stack property is accessed, which is why the "trace inside prepare" example gives the same results as the "trace from catch()" example: the prepare step doesn't actually happen until the catch. If there were some way to force V8 to invoke the stack trace formatter eagerly (at throw time) instead of lazily (at catch time), you'd be able to see all the arguments as in the "trace from before crash" case. I realize this would be at odds with the whole reason for making the stack trace formatting run lazily in the first place. But it would be helpful for some debugging scenarios.

However, getting the arguments from the old "function.arguments" property is nondesirable because of the holes that design has always had -- it doesn't work with recursive functions, and it's illegal in strict mode. It would be really nice if the CallSite object could just expose the arguments, without going through the function object for the current CallSite.

Cc: dslomov@chromium.org
Status: Accepted
Status: WorkingAsIntended
not going to touch error formatting until it is spec'ed.
Sign in to add a comment