java script関数コールの追跡
DESCRIPTION
春のJavaScript祭りにてLT。TRANSCRIPT
![Page 1: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/1.jpg)
JavaScript関数コールの追跡
@kobayan_tokyo
![Page 2: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/2.jpg)
自己紹介
@kobayan_tokyo (またはkobake)http://blog.clock-up.jp/・元ゲーム屋(10年)
・現フリーランスWeb屋(1年)・C++, C#, Java, PHP, Ruby, JavaScript, CoffeeScript
・Ruby on Rails, CakePHP, .NET Framework
・Web, Windows, Android
・Visual Studio, IntelliJ IDEA, Brackets
![Page 3: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/3.jpg)
JavaScriptの関数コールを追跡したい
人様の作ったサイトをハック解析したい
↓とりあえず関数コールの流れをザックリ見たい
![Page 4: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/4.jpg)
手がかり1:ブレークポイント
・あたりをつけて「適当な場所にブレークポイントを付ける」
・目的の関数が呼ばれたタイミングは分かる
・いちいち「これが呼ばれるだろう」というあたりを付けなければならない
・ブレークポイントに達する度にいちいち処理が止まって鬱陶しい
(我々は何か特定の問題を解決したいのではなく、構造の解析を行いたいのだ)
![Page 5: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/5.jpg)
手がかり2:関数のラップ
・あたりをつけて「適当な関数をラップする」
・目的の関数が呼ばれたタイミングは分かる
・いちいち「これが呼ばれるだろう」というあたりを付けなければならない
・ブレークポイントに達する度にいちいち処理が止まって鬱陶しい
・いまだに「あたりを付ける」必要はある
-------------------------------------------------org_hoge = hoge;hoge = function(){ console.log("---- hoge called ----"); org_hoge();}-------------------------------------------------
![Page 6: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/6.jpg)
手がかり3:Function.prototype.callhttp://stackoverflow.com/questions/4921966/live-javascript-debugging-by-recording-function-calls-and-parameters--------------------------------------------------------------------------------------------------------------------------Can you override Function.prototype.call and retrieve arguments and arguments.callee?--------------------------------------------------------------------------------------------------------------------------な・・る・・ほ・・ど・・??
- Function.prototype.call … すべての関数の呼び出し
- arguments.callee … 関数内で参照できる関数そのもの
それはつまり、
関数すべてのコールを書き換えるという暴力的な働きかけ
![Page 7: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/7.jpg)
Function.prototype.call書き換え
http://stackoverflow.com/questions/5226550/can-i-override-the-javascript-function-object-to-log-all-function-calls---------------------------------------------------------------------var origCall = Function.prototype.call;Function.prototype.call = function (thisArg) { console.log("calling a function"); var args = Array.prototype.slice.call(arguments, 1); origCall.apply(thisArg, args);};---------------------------------------------------------------------
想像には及びませんがこれは console.log 諸々自体の呼び出しにより無限ループに。
![Page 8: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/8.jpg)
書き換える範囲を絞る
http://stackoverflow.com/questions/5033836/adding-console-log-to-every-function-automatically-------------------------------------------------------------------------------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); } }}augment(function(name, fn) { console.log("-------- calling " + name + " --------");});-------------------------------------------------------------------------------
window配下の関数(?)のみラップする
![Page 9: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/9.jpg)
やってみよう
ログ多すぎ!
![Page 10: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/10.jpg)
もう少し絞る
if (typeof fn === 'function') { if(name == 'setTimeout') continue; if(name == 'clearTimeout') continue; window[name] = (function(name, fn) { var args = arguments; return function() { withFn.apply(this, args); return fn.apply(this, arguments); } })(name, fn); }
![Page 11: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/11.jpg)
絞った結果
少しログ量が減った(それでも多いけど)
![Page 12: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/12.jpg)
さらなる一歩
・グローバル関数(?)以外の関数も監視したい
・コールスタックなんかも表示したい
・行番号やファイル名なんかも出したいよね
(無名関数とかもあるし、これが無いとなんとも)
(準備時間オーバーしました)
(引き続き情報まとめ&調査していきます)
![Page 13: Java script関数コールの追跡](https://reader035.vdocuments.pub/reader035/viewer/2022080211/5594618b1a28ab9f6a8b46d1/html5/thumbnails/13.jpg)
近況
・Chromeビルド環境構築中(ディスク足りなくなりそうなので出直し中)