2008-09-04 Google Chromeについてあれこれ。
Google Chrome JavaScriptデバッガ完全マニュアル。
Google Chromeはシンプルに見えてオフラインやWebアプリショートカット作成などいろんな機能が搭載されています。
そんな中、JavaScriptデバッガがあるのも発見!
どんなもんかと思ってみてみたら、なんとコマンドラインベースのデバッガです。Firebugみたいな物を想定していたのですが、まさかgdb(GNU製C/C++デバッガ)みたいなのがブラウザに載ってるなんて・・・しかも全然情報ないし。
でも開発者にとっては、JavaScriptをランタイムでデバッグできると言うのは非常に嬉しい事ですね。そこで、Chromeデバッガの使用法についてちょっと調べてみました。
デバッガは、開発者向けメニューの中から選択する事が出来ます。立ち上げてみると、コマンドの表示結果が表示されるエリアと、コマンドを入力するテキストフィールドが並んでいるだけ、と言うシンプルなUIが表示されます。
最下部のテキストフィールドにコマンドを入力して、デバッグを行う訳ですね。
例えば、「関数x()にブレークポイントを仕掛けたい」と言う場合は「break x」などと入力します。その後、1行ずつステップ実行したい場合は「next」、現在行の関数にステップインしたい場合は「step」、変数や式の値を表示させたい場合は「print」などと入力します。
こうしたデバッグコマンドを全部一覧にしたのが下のリストです。helpコマンドでは出てこないものもあるので、現時点では結構貴重なリソースかも知れません(Chromeのソースを参照しました)。
- args・・・現在の関数における全引数の情報を表示
- break [location] <condition>・・・ブレークポイントを設定する。locationは「関数の名前」「スクリプト:関数名」「スクリプト:行番号」「スクリプト:行番号:行中の位置」のいずれか。conditionには条件式を指定し、真の場合のみブレークする。
- break_info [ブレークポイント番号]・・・現在のブレークポイントを一覧表示する。もしくは、一つのブレークポイントに関する情報を表示
- backtrace [from frame #] [to frame #]・・・関数呼び出しのバックトレースを表示
- clear <breakpoint #>・・・ブレークポイントを解除する
- continue・・・処理を続行する
- frame <frame #>・・・関数呼び出しのフレームを表示。(現在の関数が0、呼び出しもとが1...)
- help [command]・・・ヘルプを表示する
- locals・・・ローカル変数の情報を表示する
- next・・・次の行に移動する
- print <expression>・・・式の値を表示する
- scripts・・・読み込まれたスクリプト(外部ファイルも含む)の情報を表示する
- source [from line] | [<from line> <num lines>]・・・ソースを表示する。lineを省略すると、現在デバッグ中の関数を表示
- step・・・現在行の関数にステップイン
- stepout・・・現在の関数から戻る
上のコマンドをきっちり入力していくのは、結構骨の折れるタイピング作業になります。そこで、gdbと同じくコマンドの短縮型を用いる事も出来ます。例えば、さっきの「関数x()にブレークポイントを仕掛けたい」と言う場合は「b x」と入力する事も出来る訳です。
エイリアス | コマンド |
---|---|
b | break |
bi | break_info |
br | break |
bt | backtrace |
c | continue |
f | frame |
h | help |
? | help |
s | source |
n | next |
p | |
s | step |
so | stepout |
では、これらのコマンドを用いて実際のデバッグを行ってみましょう。練習用に、「ボタンを押されたら、入力された文字列を逆にして表示する」と言うサンプルを用意しました。
このサンプルのソースです。
<html> <body> <script type="text/javascript"> function reverseDisplay() { var input = document.getElementById("input").value; var out = ""; for (var i = input.length - 1; i >= 0; i--) { out += input.charAt(i); } output(out); } function output(out) { document.getElementById("output").textContent = out; } </script> <textarea id="input"></textarea><br/> <button onclick="reverseDisplay();">押してね</button><br/> <pre id="output"></pre> </body> </html>
では、ボタンが押されたときに関数「reverseDisplay()」で停止し、デバッグして行く様子を見て行きましょう。最初に止めていろいろ情報を見たあと、10行目にもブレークポイントを仕掛けてプログラムを再開し、その行にあるoutput()の呼び出しの中にステップインしています。
JavaScript Debugger attached to a.html $ b reverseDisplay <----------reverseDisplay関数にブレークポイントを設定 set breakpoint #2 $ bt <----------バックトレース表示(onclick→reverseDisplayという呼出し履歴がわかる) Frames #0 to #1 of 2: #00 reverseDisplay() file:///C:/Documents and Settings/Administrator/デスクトップ/a.html line 5 column 2 (position 31) #01 #<an HTMLButtonElement>.onclick(evt=#) file:///C:/Documents and Settings/Administrator/デスクトップ/a.html line 17 column 9 (position 143) $ bi 2 <----------ブレークポイント2の情報を表示 id=2, hit_count=0, type=function, target=reverseDisplay paused at breakpoint 2: reverseDisplay(), file:///C:/Documents and Settings/Administrator/デスクトップ/a.html 5: var input = document.getElementById("input").value; $ ls <----------ソースの表示 3: 4: function reverseDisplay() { >>>> var input = document.getElementById("input").value; 6: var out = ""; 7: for (var i = input.length - 1; i >= 0; i--) { 8: out += input.charAt(i); 9: } 10: output(out); 11: } $ n <----------1行進む 7: for (var i = input.length - 1; i >= 0; i--) { $ p input <----------変数inputの値を表示 あいうえお $ b :10 <----------10行目にもブレークポイント(#3)を設定。 set breakpoint #3 $ bi <----------全ブレークポイントの情報を表示 Num breakpoints: 2 id=2, hit_count=1, type=function, target=reverseDisplay id=3, hit_count=0, type=script, target=file:///C:/Documents and Settings/Administrator/デスクトップ/a.html, line=9 $ c <----------処理を続行。10行目まで進む paused at breakpoint 3: reverseDisplay(), file:///C:/Documents and Settings/Administrator/デスクトップ/a.html 10: output(out); $ s <----------output関数にステップイン output(out=おえういあ), file:///C:/Documents and Settings/Administrator/デスクトップ/a.html 13: document.getElementById("output").textContent = out; $ args <----------関数の引数を表示 out = "おえういあ" $ frame <----------現在のフレームを表示(output関数) #0 output, file:///C:/Documents and Settings/Administrator/デスクトップ/a.html 13: document.getElementById("output").textContent = out; $ frame 1 <----------1つ上のフレームを表示(reverseDisplay関数) #1 reverseDisplay, file:///C:/Documents and Settings/Administrator/デスクトップ/a.html 10: output(out); $ frame 2 <----------2つ上のフレームを表示(onclick関数) #2 onclick, file:///C:/Documents and Settings/Administrator/デスクトップ/a.html 17: reverseDisplay(); $ bt 1 2 <----------1〜2上のフレームをバックトレース Frames #1 to #2 of 3: #01 reverseDisplay() file:///C:/Documents and Settings/Administrator/デスクトップ/a.html line 10 column 2 (position 175) #02 #<an HTMLButtonElement>.onclick(evt=#) file:///C:/Documents and Settings/Administrator/デスクトップ/a.html line 17 column 9 (position 143) $ so <----------output関数からステップアウト reverseDisplay(), file:///C:/Documents and Settings/Administrator/デスクトップ/a.html 11: } $ locals <----------ローカル変数を表示 input = "あいうえお" out = "おえういあ" i = -1 $ c <----------処理続行、終了
Chromeのデバッガもこれで完璧ですね!
- 558 http://www.hatena.ne.jp/
- 408 http://b.hatena.ne.jp/
- 402 http://b.hatena.ne.jp/hotentry
- 247 http://secure.ddo.jp/~kaku/tdiary/
- 236 http://builder.japan.zdnet.com/member/u332219/blog/2008/09/04/entry_27013489/
- 231 http://delicious.com/
- 217 http://reader.livedoor.com/reader/
- 208 http://d.hatena.ne.jp/
- 109 http://b.hatena.ne.jp/add?mode=confirm&title=Google Chrome JavaScript%u30C7%u30D0%u30C3%u30AC%u5B8C%u5168%u30DE%u30CB%u30E5%u30A2%u30EB%u3002 - IT-Walker on hatena&url=http://d.hatena.ne.jp/Syunpei/20080904/1220500815
- 83 http://www.google.co.jp/reader/view/