Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Full callstack for multiple frames JS on IE8

I need to get a full call stack when an exception occurs in JavaScript on Internet Explorer 8. Function calls may occur between frames whose number is large.

Call stack necessary to send logs to the developers. I cannot use a debugger, because the end user does not have to deal with this problem.

The current solution for JavaScripts provided it can generate callstack (http://eriwen.com/javascript/js-stack-trace/). It is based on arguments.callee.caller. But the caller returns zero ( undefined ) if the function was called from outside the current frame. Thus callstack obtained is incomplete.

Can I get the name of a frame from which the function was called in this case?

Solution based on Active Scripts Technology gives an object of type ScriptEngine: IHTMLDocument:: get_Script (IDispatch ** p)

But casting object "script" to the interface IActiveScript fails.

*Can I get out of IE8 the link to be used for a given context ScriptEngine, to extract the necessary information to construct the callstack?

like image 932
RostislavS Avatar asked Dec 28 '10 11:12

RostislavS


1 Answers

I've found some way, which may be usefull. It utilizes the idea of callbacks.

Define next simple function at every frame:

function getCaller() { return arguments.callee.caller; }

and next functions only for top frame:

function populateStack(fn) {
    var perFrames = [];
    for (var i = 0; i < windows.length; i++) {
        var win = windows[i];
        var func = (win == this) ? fn : win.getCaller();
        var localStack = [];
        while (func) {
            localStack.push(getFuncName(func));
            func = func.caller;
        }
        perFrames.push(getWinName(win) + ": " + localStack.join(", "));
    }
    alert(perFrames.join("\n"));
}

function getWinName(win) {
    var m = win.location.toString().match(/^.*\/(.*)$/);
    return m[1];
}

function getFuncName(func) {
    var m = func.toString().match(/^function\s*(\w*)\(/);
    return m[1] || "anonymous";
}

windows should be an array at the top frame containing all window objects (i.e. frames). Usage:

window.top.populateStack.call(window, arguments.callee);

I've spent a pair of hours, trying to restore exact order, in which functions was called, but have found no solution. Only partial order (functions are correctly sorted within frames) is available in that code.

If you have several servers with different versions of code, then you may add a code, which will analyze function bodies and through that obtain more information about call order.

Hope, this helps :-)

like image 150
kirilloid Avatar answered Sep 23 '22 02:09

kirilloid