25.05.2015, 12:44
|
|
Новичок на форуме
|
|
Регистрация: 25.05.2015
Сообщений: 4
|
|
Трейсинг JS и логирование вызовов
Имеется функция на JS, запускающаяся в браузере (т.е. требующая window, window.document и т.п.)
Необходимо проследить какие методы каких объектов вызывал скрипт и какие свойства каких объектов
читал и изменял.
Существуют ли инструменты/отладчики/фреймворки для JS, позволяющие это сделать?
Я пробовал вешать "обработчик" на каждую функцию в window, проходя window рекурсивно (чтобы повесить
обработчики и функции объектов, функции объектов внутри объектов и так далее):
Код:
|
function augment(withFn) {
var name, fn;
for (name in window) {
fn = window[name];
if (typeof fn === 'function') {
window[name] = (function(name, fn) {
var args = arguments;
return function() {
withFn.apply(this, args);
return fn.apply(this, arguments);
}
})(name, fn);
}
}
} |
Но это настолько ресурсорасточительно, что сожрало больше 1 Гб памяти (IE подвесил систему и дальше я его просто убил). Нужен более гуманный способ.
Короче, к примеру, если скрипт делает
window.shit = 'a';
alert(window.shit);
, то в логе должна быть инфа о том, что:
writing window.shit
reading window.shit
calling window.alert
В задаче мне нужно знать, что из "окружения", в котором скрипт работает, он читает и вызывает.
|
|
26.05.2015, 09:35
|
Профессор
|
|
Регистрация: 12.12.2012
Сообщений: 1,398
|
|
Мне кажется что в данном случае проще пойти от обратного. Обернуть скрипт в свой scope, в котором будет эмуляция window, document и т.д. Это даст:
Во первых вы сможете отслеживать что происходит (например навесив гетторы и сетторы на все свойства эмуляции window), правда за переменными созданными через var так следить не получится. Ну и если вы сделаете свои эмуляции нерасширяемыми, то по стеку ошибок вы сможете понять что он пытался записать туда.
|
|
26.05.2015, 21:31
|
|
Новичок на форуме
|
|
Регистрация: 25.05.2015
Сообщений: 4
|
|
tsigel,
Вся проблема в том, что в скрипте выполняются миллионы строк. Руками не получится. Нужна именно автоматизация.
|
|
27.05.2015, 05:23
|
Профессор
|
|
Регистрация: 23.10.2010
Сообщений: 2,718
|
|
Вся проблема в том, что нет практического смысла. Особенно логировать присвоение значения сильный ход.
|
|
27.05.2015, 09:09
|
|
Новичок на форуме
|
|
Регистрация: 25.05.2015
Сообщений: 4
|
|
kostyanet,
Практический смысл есть. Соотносящийся с деньгами.
UPD: Логировать read/write нужно только в отношении свойств, которые лежат в window.
Для тех, что создает скрипт в процессе работы - не надо.
|
|
27.05.2015, 10:22
|
Профессор
|
|
Регистрация: 23.10.2010
Сообщений: 2,718
|
|
Напишите свой интерпретатор.
|
|
27.05.2015, 12:10
|
Профессор
|
|
Регистрация: 12.12.2012
Сообщений: 1,398
|
|
var handler = {
get: function(target, name){
alert('get element with name: ' + name);
return name in target?
target[name] : undefined;
},
set: function (target, name, value) {
alert('set element with name: ' + name);
target[name] = value;
return target;
}
};
var p = new Proxy({}, handler);
p.a;
p.b = 3;
Смотреть в ff;
Подмените window таким объектом и наслаждайтесь логами
Последний раз редактировалось tsigel, 27.05.2015 в 12:12.
|
|
28.05.2015, 09:16
|
|
Новичок на форуме
|
|
Регистрация: 25.05.2015
Сообщений: 4
|
|
tsigel,
Thx, но тут есть проблема. Я почитал мануал mozilla по прокси-объектам ( https://developer.mozilla.org/ru/doc..._Objects/Proxy) и выяснилось, что вроде бы нельзя никак именно подменить window, можно только создать новый объект - например, window2. А я не могу "заставить" скрипт использовать мой объект вместо window. Скрипт обфусцирован и велик. Мне потому и надо залогировать все вызовы и чтения свойств, что их не видно из-за обфускации (снять - не вариант). Скрипт может где-то в середине обращаться к window, складывая название объекта window по буковкам в разных callback-ах setInterval/setTimeout, и такая жесть есть. Вот в чем дело.
|
|
28.05.2015, 11:06
|
Профессор
|
|
Регистрация: 12.12.2012
Сообщений: 1,398
|
|
Сообщение от reinterpret_alexey
|
tsigel,
Thx, но тут есть проблема. Я почитал мануал mozilla по прокси-объектам (https://developer.mozilla.org/ru/doc..._Objects/Proxy) и выяснилось, что вроде бы нельзя никак именно подменить window, можно только создать новый объект - например, window2. А я не могу "заставить" скрипт использовать мой объект вместо window. Скрипт обфусцирован и велик. Мне потому и надо залогировать все вызовы и чтения свойств, что их не видно из-за обфускации (снять - не вариант). Скрипт может где-то в середине обращаться к window, складывая название объекта window по буковкам в разных callback-ах setInterval/setTimeout, и такая жесть есть. Вот в чем дело.
|
Можете, и очень просто, для этого достаточно обернуть этот скрипт в свой. Это делается примерно так:
var myWindow = new Proxy({}, {
get: function(target, name){
alert('get window element with name: ' + name);
return name in target?
target[name] : window[name];
},
set: function (target, name, value) {
alert('set window element with name: ' + name);
target[name] = value;
return target;
}
});
var myDocument = ...;
(function (window, document) {
// Здесь много вражеского кода, который надо залогировать.
}).call(myWindow, myWindow, myDocument);
Если вы обернете код который хотите прологировать в свою функцию и переопределите там window, то тот код уже никак не доберется до оригинального window (кроме разве что с помощью конструкций типа eval(...) или new Function(...) и таймаут/интервал с о строковым параметром, но их вы можете найти поиском).
Последний раз редактировалось tsigel, 28.05.2015 в 11:21.
|
|
|
|