| 
	| 
	
	| 
		
	| 
			
			 
			
				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.
 |  |  |  |