Java script関数コールの追跡

13
JavaScript 関数コールの追跡 @kobayan_tokyo

description

春のJavaScript祭りにてLT。

Transcript of Java script関数コールの追跡

Page 1: Java script関数コールの追跡

JavaScript関数コールの追跡

@kobayan_tokyo

Page 2: Java script関数コールの追跡

自己紹介

@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関数コールの追跡

JavaScriptの関数コールを追跡したい

人様の作ったサイトをハック解析したい

↓とりあえず関数コールの流れをザックリ見たい

Page 4: Java script関数コールの追跡

手がかり1:ブレークポイント

・あたりをつけて「適当な場所にブレークポイントを付ける」

・目的の関数が呼ばれたタイミングは分かる

・いちいち「これが呼ばれるだろう」というあたりを付けなければならない

・ブレークポイントに達する度にいちいち処理が止まって鬱陶しい

(我々は何か特定の問題を解決したいのではなく、構造の解析を行いたいのだ)

Page 5: Java script関数コールの追跡

手がかり2:関数のラップ

・あたりをつけて「適当な関数をラップする」

・目的の関数が呼ばれたタイミングは分かる

・いちいち「これが呼ばれるだろう」というあたりを付けなければならない

・ブレークポイントに達する度にいちいち処理が止まって鬱陶しい

・いまだに「あたりを付ける」必要はある

-------------------------------------------------org_hoge = hoge;hoge = function(){ console.log("---- hoge called ----"); org_hoge();}-------------------------------------------------

Page 6: Java script関数コールの追跡

手がかり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関数コールの追跡

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関数コールの追跡

書き換える範囲を絞る

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関数コールの追跡

やってみよう

ログ多すぎ!

Page 10: Java script関数コールの追跡

もう少し絞る

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関数コールの追跡

絞った結果

少しログ量が減った(それでも多いけど)

Page 12: Java script関数コールの追跡

さらなる一歩

・グローバル関数(?)以外の関数も監視したい

・コールスタックなんかも表示したい

・行番号やファイル名なんかも出したいよね

(無名関数とかもあるし、これが無いとなんとも)

(準備時間オーバーしました)

(引き続き情報まとめ&調査していきます)

Page 13: Java script関数コールの追跡

近況

・Chromeビルド環境構築中(ディスク足りなくなりそうなので出直し中)