はじめてのNode.js:Node.jsアプリケーションのデバッグ
Node.jsアプリケーションのデバッグを行う際に、変数の値や実行中の関数、実行した関数の戻り値といったプログラムの内部的な状態を外部から確認することで、デバッグの効率が大幅に向上する。本記事ではこれらを実現できるNode.js組み込みのデバッグ機能や、GUIで操作できるデバッガ「node-inspector」について紹介する。
【連載】はじめてのNode.js
- 第1回:Node.jsのイベントシステムを知る
- 第2回:Node.js内でバイナリデータを扱うための「Buffer」クラス
- 第3回:Node.jsアプリケーションのデバッグ
- 第4回:マルチプロセスアプリケーションを作成する
本記事について
本記事は、3月13日にソフトバンク クリエイティブより発売された書籍「はじめてのNode.js -サーバーサイドJavaScriptでWebアプリを開発する-」から、「第7章 Node.jsアプリケーションのデバッグ方法」の一部を抜き出し再構成したものです。
大型本: 384ページ、価格:3,045円(税込)、ISBN: 978-4797370904
Node.js組み込みのデバッガを使う
nodeコマンドには、CUIで操作できるデバッグ機能が組み込まれている。実行中のコードを表示したり、変数や関数の戻り値を表示する、といったシンプルな機能のみを持つデバッガであるが、別途ツールなどをインストールすることなしに手軽にプログラムの実行状況を確認できる。
デバッグ機能を使うには、node debugコマンドを使用する。
$ node debug <実行するスクリプト名>
たとえば、次のようなプログラム(sample7-2.js)をデバッグする例を考えよう。
console.log('hello, world'); function foo() { console.log('hello, foo'); return 100; } var bar = 'This is a pen.'; var http = require('http'); var i = foo(); console.log(i);
このプログラムをデバッグする場合、次のようにする。
$ node debug sample7-2.js < debugger listening on port 5858 connecting... ok break in sample7-2.js:3 1 // This is sample program 7-2 2 3 console.log('hello, world'); 4 5 function foo() { debug>
node debugコマンドでは、実行するモジュールの一番最初の命令文を実行する直前でプログラムが一時停止され、画面に「debug>」というプロンプト(デバッグプロンプト)が表示される。この例の場合、「break in sample7-2.js:3」と表示されているが、これは「sample7-2.js」ファイルの3行目の直前でプログラムが停止している、ということを意味している。
一時停止しているプログラムの実行を開始するには、デバッグプロンプトが表示された状態でcont(「continue」の略)、もしくはcコマンドを実行する。するとプログラムの実行が再開され、その結果がコンソールに表示される。
debug> c < hello, world < hello, foo < 100 program terminated debug>
プログラムの実行が完了すると、コンソールに「program terminated」と表示される。この状態でrunもしくはrコマンドを実行すると、プログラムを最初から再度実行させることができる。
debug> r < debugger listening on port 5858 connecting... ok break in sample7-2.js:3 1 // This is sample program 7-2 2 3 console.log('hello, world'); 4 5 function foo() { debug>
contもしくはcコマンドの代わりにnextもしくはnコマンドを実行すると、プログラムを1ステップずつ実行できる。
debug> n break in sample7-2.js:10 < hello, world 8 } 9 10 var bar = 'This is a pen.'; 11 var http = require('http'); 12 debug>
この例の場合、プログラムの3行目にある「console.log(‘hello, world’);」が実行されてコンソールに「hello, world」という文字列が表示され、次の命令文である10行目の直前でプログラムが停止している。
nextコマンドでは、このように命令文単位でプログラムを実行する。そのため、たとえば「var i = foo();」というような関数呼び出しを含む命令文については、その結果のみを表示する。
debug> n break in sample7-2.js:13 11 var http = require('http'); 12 13 var i = foo(); 14 console.log(i); 15 debug> n < hello, foo break in sample7-2.js:14 12 13 var i = foo(); 14 console.log(i); 15 16 debug>
命令文内で呼び出されている関数をステップ実行したい場合は、nextコマンドの代わりにstepもしくはsコマンドを利用する。stepもしくはsコマンドを実行すると、呼び出された関数内の最初の命令の直前で実行が停止される。この操作は「ステップイン」と呼ばれている。
debug> n break in sample7-2.js:13 11 var http = require('http'); 12 13 var i = foo(); 14 console.log(i); 15 debug> s break in sample7-2.js:6 4 5 function foo() { 6 console.log('hello, foo'); 7 return 100; 8 } debug>
また、outもしくはoコマンドを実行すると、実行中の関数から抜けるまでプログラムを実行し、次の命令文の直前で停止する。この操作は「ステップアウト」と呼ばれている。
debug> o < hello, foo break in sample7-2.js:14 12 13 var i = foo(); 14 console.log(i); 15 16 debug>
なお、Node.jsでは非同期にプログラムが実行されるため、プロンプトが表示されている場合でもバックグラウンドでプログラムが動作していることがある。この状態でpauseコマンドを実行すると、バックグラウンドで実行されているプログラムを一時停止させることができる。
変数の値をウォッチする
デバッガには実行中プログラムの変数の値を確認する「ウォッチ」機能もある。これは、ステップ実行を行うごとにあらかじめ指定しておいた式を評価しその結果を表示する、というものだ。ウォッチ機能を使うには、デバッグプロンプトが表示された状態でwatchコマンドを実行する。
watch('評価する式')
watchコマンドの引数には、評価する式を文字列で指定する。たとえば変数iをウォッチするには、次のようにする。
$ node debug sample7-2.js < debugger listening on port 5858 connecting... ok break in sample7-2.js:3 1 // This is sample program 7-2 2 3 console.log('hello, world'); 4 5 function foo() { debug> watch('i') debug>
また、ウォッチを解除するには、unwatchコマンドを実行すればよい。
unwatch('<評価する式>')
ブレークポイントを設定する
プログラムの不具合を見つける際に、疑わしい個所までいちいちステップ実行で進めて行くのは面倒だ。そのため、デバッガには指定した個所でプログラムの実行を一時停止させる機能が用意されている。ここで一時停止させる個所を「ブレークポイント」と呼ぶ。
ブレークポイントを設定するには、setBreakpointもしくはsbコマンドを実行する。
setBreakpoint(filename, line) sb(filename, line)
sbはsetBreakpointのエイリアス(別名)であり、その動作はどちらも同じだ。filename引数にはブレークポイントを設定したいスクリプトファイル名を文字列で指定し、line引数にはブレークポイントを設定したい行番号を数値で指定する。なお、filename引数を省略した場合は現在実行しているファイルが対象となり、またline引数とfilename引数の両方を省略した場合は次に実行される行にブレークポイントが設定される。
たとえば、現在実行しているファイルの10行目にブレークポイントを設定するには、次のようにする。
debug> setBreakpoint(10) 1 // This is sample program 7-2 2 3 console.log('hello, world'); 4 5 function foo() { 6 console.log('hello, foo'); 7 return 100; 8 }
ブレークポイントを設定した後にcコマンドで実行を開始させると、ブレークポイントを設定した行で動作が一時停止する。このとき、ブレークポイントが設定された行には行番号の前に「*」マークが表示される。
debug> c < hello, world break in sample7-2.js:10 8 } 9 *10 var bar = 'This is a pen.'; 11 var http = require('http'); 12 debug>
ブレークポイントを解除するには、clearBreakpointもしくはcbコマンドを使用する。
clearBreakpoint(filename, line) cb(filename, line)
そのほか、デバッガで使用できるコマンド一覧は表1のとおりだ。
コマンド名 | 説明 |
---|---|
cont、c | 実行を再開する |
next、n | 次の命令を実行して一時停止する(ステップ実行) |
step、s | 次の関数の先頭で一時停止する(ステップイン) |
out、o | 実行中関数から抜けるまで実行して一時停止する(ステップアウト) |
pause | コードの実行を一時停止する |
setBreakpoint()、sb() | ブレークポイントを設定する |
clearBreakpoint()、cb() | ブレークポイントを解除する |
backtrace、bt | バックトレースを表示する |
list(number) | 次に実行する命令の前後のソースコードをnumber引数で指定した行数ずつ表示する |
watch(expr) | expr引数で指定した式をウォッチする |
unwatch(expr) | expr引数で指定した式のウォッチを解除する |
watcher | ウォッチしている式とその値を一覧表示する |
repl | replを開始する |
run | プログラムの実行を開始する |
restart | プログラムを先頭から再実行する |
kill | スクリプトの実行を強制終了(KILL)する |
scripts | ロードされているスクリプトを一覧表示する |
version | V8のバージョンを表示する |
node-inspectorを使う
node-inspectorは、Node.jsプログラムをGUIでデバッグするためのWebアプリケーションだ。搭載している機能自体はNode.jsのデバッガと同じだが、ソースコードや変数の値をGUIで確認しながらデバッグを行えるのが特徴だ。
node-inspectorは、npmコマンドでインストールできる。
$ npm install node-inspector
node-inspectorでデバッグを行うには、まずデバッグしたいプログラムを–debug-brkオプション付きで実行する。
$ node --debug-brk sample7-2.js debugger listening on port 5858
この状態で、別のコンソールからnode-inspectorを起動する。
$ ./node_modules/.bin/node-inspector info - socket.io started visit http://0.0.0.0:8080/debug?port=5858 to start debugging
ここで表示されているURL(この場合0.0.0.0:8080)にWebブラウザでアクセスすると、node-inspectorの画面が表示される(図1)。
node-inspectorでは一般的なGUIの統合開発環境のように実行中のソースコードやコールスタック、変数の値などがGUIで表示される(図2)。右上のツールバーではステップ実行などの操作が可能だ。また、「Console」タブではreplコンソールにアクセスでき、ここで変数の値を確認したり、関数の実行が行える。
【連載】はじめてのNode.js
- 第1回:Node.jsのイベントシステムを知る
- 第2回:Node.js内でバイナリデータを扱うための「Buffer」クラス
- 第3回:Node.jsアプリケーションのデバッグ
- 第4回:マルチプロセスアプリケーションを作成する
本記事について
本記事は、3月13日にソフトバンク クリエイティブより発売された書籍「はじめてのNode.js -サーバーサイドJavaScriptでWebアプリを開発する-」から、「第7章 Node.jsアプリケーションのデバッグ方法」の一部を抜き出し再構成したものです。
大型本: 384ページ、価格:3,045円(税込)、ISBN: 978-4797370904