Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 25.05.2015, 12:44
Аватар для reinterpret_alexey
Новичок на форуме
Отправить личное сообщение для reinterpret_alexey Посмотреть профиль Найти все сообщения от reinterpret_alexey
 
Регистрация: 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


В задаче мне нужно знать, что из "окружения", в котором скрипт работает, он читает и вызывает.
Ответить с цитированием
  #2 (permalink)  
Старый 26.05.2015, 09:35
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 12.12.2012
Сообщений: 1,398

Мне кажется что в данном случае проще пойти от обратного. Обернуть скрипт в свой scope, в котором будет эмуляция window, document и т.д. Это даст:
Во первых вы сможете отслеживать что происходит (например навесив гетторы и сетторы на все свойства эмуляции window), правда за переменными созданными через var так следить не получится. Ну и если вы сделаете свои эмуляции нерасширяемыми, то по стеку ошибок вы сможете понять что он пытался записать туда.
Ответить с цитированием
  #3 (permalink)  
Старый 26.05.2015, 21:31
Аватар для reinterpret_alexey
Новичок на форуме
Отправить личное сообщение для reinterpret_alexey Посмотреть профиль Найти все сообщения от reinterpret_alexey
 
Регистрация: 25.05.2015
Сообщений: 4

tsigel,

Вся проблема в том, что в скрипте выполняются миллионы строк. Руками не получится. Нужна именно автоматизация.
Ответить с цитированием
  #4 (permalink)  
Старый 27.05.2015, 05:23
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

Вся проблема в том, что нет практического смысла. Особенно логировать присвоение значения сильный ход.
Ответить с цитированием
  #5 (permalink)  
Старый 27.05.2015, 09:09
Аватар для reinterpret_alexey
Новичок на форуме
Отправить личное сообщение для reinterpret_alexey Посмотреть профиль Найти все сообщения от reinterpret_alexey
 
Регистрация: 25.05.2015
Сообщений: 4

kostyanet,

Практический смысл есть. Соотносящийся с деньгами.
UPD: Логировать read/write нужно только в отношении свойств, которые лежат в window.
Для тех, что создает скрипт в процессе работы - не надо.
Ответить с цитированием
  #6 (permalink)  
Старый 27.05.2015, 10:22
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

Напишите свой интерпретатор.
Ответить с цитированием
  #7 (permalink)  
Старый 27.05.2015, 12:10
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 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.
Ответить с цитированием
  #8 (permalink)  
Старый 28.05.2015, 09:16
Аватар для reinterpret_alexey
Новичок на форуме
Отправить личное сообщение для reinterpret_alexey Посмотреть профиль Найти все сообщения от reinterpret_alexey
 
Регистрация: 25.05.2015
Сообщений: 4

tsigel,

Thx, но тут есть проблема. Я почитал мануал mozilla по прокси-объектам (https://developer.mozilla.org/ru/doc..._Objects/Proxy) и выяснилось, что вроде бы нельзя никак именно подменить window, можно только создать новый объект - например, window2. А я не могу "заставить" скрипт использовать мой объект вместо window. Скрипт обфусцирован и велик. Мне потому и надо залогировать все вызовы и чтения свойств, что их не видно из-за обфускации (снять - не вариант). Скрипт может где-то в середине обращаться к window, складывая название объекта window по буковкам в разных callback-ах setInterval/setTimeout, и такая жесть есть. Вот в чем дело.
Ответить с цитированием
  #9 (permalink)  
Старый 28.05.2015, 11:06
Профессор
Отправить личное сообщение для tsigel Посмотреть профиль Найти все сообщения от tsigel
 
Регистрация: 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.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Операционная Система на JS Icat Общие вопросы Javascript 3 17.04.2018 22:54
Вывыод контента через JS inet_boy Элементы интерфейса 0 18.11.2013 03:00
Не получается вставить код js в HTML garmoni Элементы интерфейса 3 05.09.2013 05:56
Вставка кода js с помощью js Alice Общие вопросы Javascript 1 12.06.2013 19:05