Полный стек вызовов для нескольких кадров JS на IE8 - PullRequest
8 голосов
/ 28 декабря 2010

Мне нужно получить полный стек вызовов при возникновении исключения в JavaScript в Internet Explorer 8. Вызовы функций могут происходить между кадрами, число которых велико.

Стек вызовов, необходимый для отправки журналов разработчикам.Я не могу использовать отладчик, потому что конечный пользователь не должен иметь дело с этой проблемой.

Текущее решение для скриптов Java, если оно может генерировать стек вызовов (http://eriwen.com/javascript/js-stack-trace/). Оно основано на arguments.callee.вызывающая сторона. Но вызывающая функция возвращает ноль (не определено), если функция была вызвана из-за пределов текущего кадра. Таким образом, полученный callstack является неполным.

Могу ли я получить имя кадра, из которого была вызвана функцияв этом случае?

Решение, основанное на технологии активных сценариев, дает объект типа ScriptEngine: IHTMLDocument :: get_Script (IDispatch ** p)

Но приведение объекта "script" кИнтерфейс IActiveScript терпит неудачу.

* Могу ли я получить из IE8 ссылку, которая будет использоваться для данного контекста ScriptEngine, чтобы извлечь необходимую информацию для построения стека вызовов?

1 Ответ

2 голосов
/ 06 февраля 2011

Я нашел какой-то способ, который может быть полезным.Он использует идею обратных вызовов.

Определить следующую простую функцию в каждом кадре:

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

и следующие функции только для верхнего кадра:

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";
}

окна должны бытьмассив в верхнем фрейме, содержащий все объекты окна (т.е. фреймы).Использование:

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

Я потратил пару часов, пытаясь восстановить точный порядок, в котором вызывались функции, но не нашел решения.В этом коде доступен только частичный порядок (функции правильно отсортированы внутри фреймов).

Если у вас есть несколько серверов с разными версиями кода, вы можете добавить код, который будет анализировать тела функций и таким образом получатьбольше информации о заказе звонка.

Надеюсь, это поможет: -)

...