22
16

More than 5 years have passed since last update.

2017年 Perl5 との戦いに生き残るための最高の開発環境を手に入れる - リモートデバッグ 編

Last updated at Posted at 2017-01-23

はじめに

前回 の記事の続きとなります。前回構築した開発環境を元にして、今度はリモートデバッグができる環境をつくります。

この記事を読むとできるようになること

この記事を最後まで読むと、こんな事ができるようになります。

00_完成図.gif

つまり、リモートサーバ上で実行されている Perl5 スクリプトが実行された際に、IDE 上でデバッガを利用して変数の状態を可視化しながらデバッグが行えるようになります。 Perl5 で書かれた CGI のデバッグというと print デバッグ頼みになりがちかと思いますが、この記事で解説する環境構築を行うことで一気に Perl5 でもモダンな開発ができるようになります。

準備

前回 の記事で、IntelliJ IDEA Community Edition を用いた Perl5 (以下、Perl) の開発環境の構築について説明しました。まだ IntelliJ IDEA Community Edition での Perl 開発環境を構築されていない場合は、先に 前回の記事 を御覧ください。
また、WebStorm などの IntelliJ IDEA Community Edition 以外の JetBrains 社製 IDE を使われる方で、まだ環境構築をされていない方は こちら の記事の内容も併せてお読みいただくと良いかもしれません。

JetBrains 社で公開されている IDE は基本的に有償版でなければリモートデバッグ機能は使えない模様ですが、この記事で解説する Perl のリモートデバッグについては 無償版の Community Edition でも利用できます。 したがって、Perl のリモートデバッグは完全に無償で行うことができます。

この記事では前回同様、IntelliJ IDEA Community Edition 2016.3.3 (以下、IntelliJ IDEA) を用いて解説していきます。

また、この記事ではテスト用のリモート環境として Vagrant で VirtualBox 上に Ubuntu14.04 (Trusty) の VM を立て、その上でリモート環境用の Docker コンテナを利用するという方法を取っています。Vagrant だけを使う場合、Docker だけを使う場合、あるいは別の物理マシン上で Perl を動作させる場合のいずれであっても、読み替えは難しくないかと思います。

この記事で使用する VM 環境を作るためのスクリプトは GitHub のリポジトリ https://github.com/AnnPin/idea-perl5-remote-debug-sample として公開しておりますので、自分で試してみたいという方はご自由にダウンロードするなり clone を取るなりして活用してください。

なお、前回と同様に Perl6 については恐らく対応していないかと思いますので、Perl5 限定の開発環境となるかと思います。 ご了承下さい。

リモート環境を構築するためのサンプルスクリプトを取得する

まずは、リモート環境用の VM を作成するためのスクリプトを取得します。GitHub から clone を取得し、リポジトリ内に存在している dev ディレクトリをデスクトップに配置します。
事前に VirtualBoxVagrant をインストールしておいて下さい。テスト環境は macOS Yosemite 10.10.5 であり、VirtualBox 5.1.14Vagrant 1.9.1 で動作確認を行っています。

# GitHub からサンプルスクリプトを取得.
$ git clone git@github.com:AnnPin/idea-perl5-remote-debug-sample.git

# 取得したリポジトリ内へ移動.
$ cd idea-perl5-remote-debug-sample

# dev ディレクトリをデスクトップへ移動.
$ mv dev ~/Desktop

# デスクトップ上の dev ディレクトリへ移動.
$ cd ~/Desktop/dev

IntelliJ IDEA でプロジェクトを作成する

リモートデバッグを始める前に、まずはローカル環境で動作する Perl プロジェクトを IntelliJ IDEA で作成しましょう。IntelliJ IDEA を起動し、以下のウィンドウで Create New Project を作成します。

01_セットアップ001.png

左側のメニューから Perl5 module を選択して Next をクリックします。

01_セットアップ002.png

IntelliJ IDEA で使用する Perl5 インタプリタを選択します。前回 までの内容を行った後ならば既に Perl5 インタプリタが登録されているかと思いますが、まだ登録されていない場合あるいは新たにインタプリタを追加したい場合は Configure... をクリックして Perl5 インタプリタを追加しておいて下さい。

Perl5 インタプリタが選択できたら、Next をクリックします。

01_セットアップ003.png

次に Perl プロジェクトの名前とそのプロジェクトが配置されるディレクトリを指定します。

ここで注意点があります。この記事で紹介しているリモート環境用のサンプルスクリプトを用いて VM を構築する場合、ここで作成する Perl スクリプトのコードは、そのままホストマシンと VM との間の共有フォルダに配置してください。 このようにすることで、IntelliJ IDEA 上でプロジェクト中の Perl スクリプトに対して加えた変更が、リモート環境中の Perl スクリプトに即時反映されるため、開発が容易になります。先程 GitHub からサンプルスクリプトを取得してきた際に、リポジトリ内の dev ディレクトリをデスクトップに移動させました。後から Vagrant で VM を立ち上げますが、その際に Vagrant で作成される VM および VM 中で立ち上げる Docker コンテナは ~/Desktop/dev/files/docker-perl-debug/www/cgi-bin 中に配置された Perl プロジェクトを CGI として認識するように設定されています。

したがってサンプルスクリプトを使用している場合、ここでは以下の画像を参考に ~/Desktop/dev/files/docker-perl-debug/www/cgi-bin 中に Perl プロジェクトを作成するようにしてください。

なお、サンプルスクリプト中にはこれから作成しようとしている remote-debug-test は既に完成された状態で含まれているため、同じ名前のプロジェクト名にしようとしている場合には一度 remote-debug-test ディレクトリを削除するか、あるいは別のプロジェクト名を設定するようにしてください。

プロジェクト名とプロジェクトの保存ディレクトリが指定できたら、Finish をクリックして下さい。

01_セットアップ004.png

まだ存在しないディレクトリ名を指定していた場合には以下のようなアラートが表示されるかと思いますが、そのまま OK ボタンをクリックして大丈夫です。

01_セットアップ005.png

プロジェクトが作成されると、以下のような画面となります。ウィンドウ左側のプロジェクトツールウィンドウが表示されていない場合、Windows では Alt + 1 キー、macOS では Command + 1 キーを入力してプロジェクトツールウィンドウが以下のように表示された状態としておいてください。

01_セットアップ006.png

それでは、簡単なサンプルスクリプトを作成しましょう。左側のプロジェクトツールウィンドウ上でプロジェクの名前 (ここでは remote-debug-test) を右クリックし、表示されるコンテキストメニューから New -> Perl5 File と選択します。

01_セットアップ007.png

作成するサンプルスクリプトのファイル名を入力します。ここでは test.pl というサンプルスクリプトを作成しようとしているので、Name に test と入力します。Name には .pl などの拡張子は入力しないように気をつけて下さい。また、Kind には Script を選択します。

選択が完了したら、OK をクリックしましょう。

01_セットアップ008.png

これにより、ウィンドウ左側のプロジェクトツールウィンドウに test.pl が追加されます。

それでは、サンプルスクリプトを作成しましょう。test.pl の内容を以下のように書き換えてみて下さい。

#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';

print("Hello, remote debugging!\n");

my $res = multiply(8, 8);
print("$res\n");

sub multiply {
    my $n = shift;
    my $times = shift;
    my $acc = 0;

    for (my $i = 0; $i < $times; $i++) {
        $acc += $n;
    }

    return $acc;
}

書き換えが完了すると、以下の図のようになります。

01_セットアップ009.png

では、このサンプルスクリプトを実行してみましょう。ウィンドウ左側のプロジェクトツールウィンドウ上でプロジェクト名を右クリックし、表示されるコンテキストメニュー中から Run 'test.pl' をクリックします。

01_セットアップ010.png

問題なくスクリプトが実行されれば、以下の図のようにプログラムの実行結果が画面下部のコンソールに出力されるはずです。

01_セットアップ011.png

以上で、ローカル環境で動作する Perl のプロジェクトが作成できました。ローカル環境側に Devel::Camelcadedb をインストールしているならば、IDE 上からデバッグを実行することもできます。詳細は、前回の記事 を参照して下さい。

リモート環境用のサーバを準備する

さて、それではリモート環境用の VM を準備しましょう。この記事ではサンプルスクリプトを用いて、Vagrant と Docker を用いた VM および コンテナ をリモート環境サーバとして利用します。

ターミナルから、デスクトップ上にコピーした dev ディレクトリ内に移動し、Vagrant を用いて Ubuntu14.04(Trusty) の VM を作成します。 Vagrant で作成される VM はメモリを 1.5GB に割り当て、ホストオンリーネットワークにおける IP アドレスを 192.168.64.64 と割り当てています。また、dev ディレクトリ内の files ディレクトリを VM の /vagrant にマウントするように設定しています。これらの設定は同じく dev ディレクトリ中の Vagrantfile を編集することで変更できます。メモリは 1.5GB 以外に設定されても大丈夫ですが、512MB 程度だと CPAN の実行がメモリ不足で落ちてしまい、Devel::Camelcadedb のインストールに失敗してしまう可能性があるので注意して下さい。IP アドレスは自由に変更していただいてもOKです。

(この記事中のスクリーンショットでは dev.localhost というホスト名を 192.168.64.64 の VM のアドレスに設定した状態となっています。)

$ cd ~/Desktop/dev
$ vagrant up

vagrant up コマンドにより、VirtualBox 上に自動的に Ubuntu14.04 (Trusty) の VM が作成されます。また、プロビジョニング設定を provision.sh に記述しているため、vagrant up コマンド中に Docker のインストールまでまとめて実行されます。

以下のスクリーンショットは VM の初回起動ではないためほとんどログが出力されていませんが、VM の初回起動時にはこれよりもたくさんのログ情報が表示されるかと思います。

02_サーバ001.png

vagrant up コマンドが完了したら、VM が正しく起動できているか確認してみましょう。以下のコマンドを実行して下さい。

$ vagrant status

無事に VM が起動できているならば、status は以下のように running となるはずです。

02_サーバ002.png

無事に VM が起動できたら、VM 中に ssh でログインを行いましょう。以下のコマンドで VM 中にログインができます。

$ vagrant ssh

無事にログインができた場合、ターミナルのプロンプトが vagrant@vagrant-ubuntu-trusty-64 のように VM のものに変化するのがわかるかと思います。

では、cd コマンドを使ってディレクトリを移動し、ホストマシンとの共有フォルダ内に移動しましょう。

$ cd /vagrant
$ cd docker-perl-debug/

以下にこの作業のスクリーンショットを示します。

02_サーバ003.png

無事に docker-perl-debug ディレクトリ内に移動できたら、次に実際に Perl が動作する Docker コンテナのための Docker イメージの作成およびコンテナの立ち上げを行います。今回のサンプルスクリプトでは、docker-perl-debug 内の Makefile にイメージの作成からコンテナの立ち上げまでを自動的に行うように設定を記述しています。したがって、docker-perl-debug ディレクトリ内に移動できたら、次のコマンドを実行するだけで Docker コンテナが起動します。

$ make setup-nc

02_サーバ004.png

無事にコンテナが起動すると、以下のような画面となります。

02_サーバ005.png

コンテナの作成はこのように自動化されていますが、中で行っていることはそんなに大した内容ではありません。大体、以下のようなことを行っています。
- Ubuntu14.04 の Docker イメージを元にして Apache をインストールするように Dockerfile に設定.
- コンテナ内のドキュメントルートを /www にするように 000-default.conf に設定.
- し、/www/cgi-bin 中で CGI が動作するように apache2.conf に設定.
- Apache が CGI モジュールが有効になった状態で起動するように setup.sh に設定.
- docker-perl-debug ディレクトリ中の www ディレクトリがコンテナ中の /www、すなわちドキュメントルートにマウントされるように Makefile に設定.

コンテナセットアップ時のスクリプトの詳細に関しては、リポジトリ中の実際のスクリプトの記述を参照していただければと思います。

問題なくコンテナが起動したならば、次にコンテナ内へとログインを行いましょう。Makefile 中に make bash というコマンドでコンテナ内にログインができるように設定を記述してあります。

$ make bash

コンテナ内へのログインが成功すると、再びプロンプトが root@(コンテナのハッシュ値) のように変化します。コンテナ内では /www がドキュメントルートになっており、このディレクトリは VM 環境中の /vagrant/docker-perl-debug/www がマウントされるようになっています。したがって、この中の cgi-bin ディレクトリ中に先程 IntelliJ IDEA 上で作成した Perl プロジェクトが配置されるようになっています。以下のように cd コマンドを実行することでディレクトリ中に移動してみて下さい。

$ cd /www/cgi-bin/remote-debug-test/

以下にこの作業のスクリーンショットを示します。

02_サーバ006.png

以上で、リモート環境として動作ささせる VM および コンテナ の準備が完了しました。

リモートデバッグを試してみる

さて、それでは IntelliJ IDEA 上で作成した Perl スクリプトである test.plVM 中のコンテナ環境中で実行し、そのリモートデバッグを IntelliJ IDEA 上で行ってみましょう。

まずは、前回までと同様に Perl が動作する環境には Devel::Camelcadedb モジュールのインストールが必要となります。コンテナ環境中で以下のコマンドを実行してみて下さい。

$ cpan install Devel::Camelcadedb

CPAN から Devel::Camelcadedb のインストールを行います。実は、先程立ち上げた Docker コンテナはセットアップ時に Devel::Camelcadedb をインストールするように設定されているため、このコマンドを実行すると 既にインストールされていて最新である (Devel::Camelcadedb is up to date (1.6.1.6).) と表示されるかと思います。

ローカル環境でのデバッグとは異なり、リモートデバッグを行うにはさらにいくつか追加でコンテナ環境側に設定を行います。Perl for IntelliJ IDEA プラグインの公式リポジトリの Wikiページ によると、リモート環境側には Perl を実行するユーザ に対して 3 つの環境変数の登録が必要 となっています。3 つの環境変数はそれぞれ以下のとおりです。

  • PERL5_DEBUG_ROLE

    • リモート環境中の Perl プロセスの役割を設定する. "server" あるいは "client" を指定する.
    • リモートデバッグを行う際、ローカル環境中の IDE をリモート環境中の Perl プロセスに接続させる ("server") のか、あるいは リモート環境中の Perl プロセスをローカル環境中の IDE に接続させる ("client") のかを指定する.
  • PERL5_DEBUG_HOST

    • Perl プロセスが "server" として振る舞うように設定されている場合はリモート環境のアドレス ("localhost") を指定し、Perl プロセスが "client" として振る舞うように設定されている場合は IDE が動作しているローカル環境のアドレスを指定する.
  • PERL5_DEBUG_PORT

    • リモートデバッグを行う際に使用するポート番号を設定する. Perl プロセスが "server" として振る舞うように設定されている場合はリモート環境のポート番号を指定し、Perl プロセスが "client" として振る舞うように設定されている場合は IDE が動作しているローカル環境のポート番号を指定する.

どのような設定でリモートデバッグを行うのかによって、設定内容は変わってくるかと思います。ここでは、リモート環境中の Perl プロセスからローカル環境中の IDE へと接続をするように設定を行ってみます。

この設定の場合、PERL5_DEBUG_ROLE"client" となり、PERL5_DEBUG_HOST は IDE が動作しているローカル環境のアドレス、PERL5_DEBUG_PORT はリモートデバッグを行うための IDE が動作しているローカル環境のポート番号を指定することとなります。

今回の場合、PERL5_DEBUG_HOST にはVirtualBox の VM 上で動作している Docker コンテナ中からホストマシンのアドレスを入力することとなりますが、こちら によると、VirtualBox の VM 内からはホストマシンは 10.0.2.2 というアドレスで参照することができるようになっているようです。したがって、ここではPERL5_DEBUG_HOST には 10.0.2.2 を設定します。

また、PERL5_DEBUG_PORT の値はここでは 18080 にしようかと思いますが、特にこのポート番号でなければならないというものではありません。別のポート番号を指定していただいても大丈夫です。ただし、後でからこのポート番号を IDE 側にも入力するため、PERL5_DEBUG_PORT と IDE 側のポート番号の設定は必ず同じポート番号を指定するようにしてください。

Bash では環境変数の設定は export コマンドで行うことができます。したがって、以下のように入力して下さい。

$ export PERL5_DEBUG_ROLE="client"
$ export PERL5_DEBUG_HOST="10.0.2.2"
$ export PERL5_DEBUG_PORT="18080"

この作業のスクリーンショットを以下に示します。

03_接続テスト001.png

ここまででリモート環境側への設定は完了しました。再び IntelliJ IDEA へと戻り、画面上部のメニューから Run -> Edit Configurations... を開いて下さい。

03_接続テスト002.png

すると、Run/Debug Configurations ウィンドウが表示されます。ここにリモートデバッグ実行時の設定情報を記述します。ウィンドウ左上の + をクリックしましょう。

03_接続テスト003.png

Add New Configuration メニューが表示されるので、この中から Perl Remote Debugging を選択してクリックします。

03_接続テスト004.png

すると、Perl のリモートデバッグ用の設定が新たに追加されます。このリモートデバッグ用の設定を以下のように指定します。

  • Name: リモートデバッグ設定の名前 (ここでは remote debug としている)
  • Remote project root: リモート環境中におけるプロジェクトディレクトリの位置となるので、/www/cgi-bin/remote-debug-test とする。
  • Connection mode: Perl process connects to the IDE とする。
  • Server host: localhost とする。
  • Server port: 18080 とする。

この中で、Perl プロジェクトの名前が remote-debug-test ではない場合には、Remote project root の値も併せて修正して下さい。また、今回はリモート環境中の Perl プロセスからローカル環境中の IDE にアクセスをするように設定したいので、Connection mode は Perl process connects to the IDE、Server host は localhost となります。

Server port は必ずしも 18080 である必要はありませんが、リモート環境中の環境変数 PERL5_DEBUG_PORT で設定した値と同じ値を入力するようにして下さい。

設定が完了したら、OK をクリックしましょう。

03_接続テスト005.png

さて、いよいよリモートデバッグを試してみます。IntelliJ IDEA のエディター上でリモートデバッグ時に動作を停止させたい行にブレークポイントを設定しましょう。

03_接続テスト006.png

ブレークポイントが設定できたら、画面上部のメニューから Run -> Debug 'remote debug' をクリックして先程設定したリモートデバッグ用の構成情報でデバッグを開始させます。

03_接続テスト007.png

デバッグが開始されると、IDE 上ではプログラムは実行されることなくただ画面下部のコンソール上に Listening on localhost:18080... という表示が出力されます。これは、IDE がリモート環境中の Perl スクリプトが実行された際に IDE に接続してくるのを待機している状態です。

したがって、リモート環境中から Perl スクリプトを実行してみましょう。注意点として、リモート環境中で Perl スクリプトを実行する場合には必ず、/usr/bin/perl -d:Camelcadedb スクリプト名 というように、必ず -d オプションで Camelcadedb を読み込ませるようにしてください。なお、この記事で使用しているリモート環境でリモートデバッグを試している場合には、ここでは Perl を実行する際に /usr/bin/perl のようにフルパスで指定するようにしてください。理由は次のセクションで説明しますが、取り敢えずこの段階では /usr/bin/perl -d:Camelcadedb スクリプト名 というフォーマットなのだと思っておいて下さい。

$ /usr/bin/perl -d:Camelcadedb test.pl

ブレークポイントの設定からリモートデバッグの実行までを行っている様子を以下に示しますね。

03_接続テスト008.gif

どうでしょうか? リモート環境中で Perl スクリプトが実行された直後に IDE 上でプログラムの動作がブレークポイントで停止しているのを確認できますね。このようにして、リモート環境中で動作している Perl プログラムをローカル環境の IDE 上でデバッグを行うことができます。

CGI のリモートデバッグ

事前準備(サンプルスクリプトでは既に設定済み)

さて、先程のセクションまででローカル環境中で動作している IntelliJ IDEA でリモート環境中で動作している Perl スクリプトをデバッグすることができるということまで紹介しました。

折角 Perl スクリプトのリモートデバッグができるようになったのだから、最後はやはり CGI として動作している Perl スクリプトのリモートデバッグにも挑戦しましょう。これができるようになることで、この記事の最初にお見せした ブラウザ上での渡された入力をデバッガを用いて可視化しながら、ローカル環境の IDE でデバッグできる環境 を構築できるようになります。

サンプルスクリプトを使用して今までの記事通りにここまで作業を進めてこられている場合、実は CGI のデバッグに必要な設定は既に Docker コンテナ側に設定されている状態となっています。

具体的には、以下のように設定されている必要があります。
1. リモート環境中に perl がインストールされており、Devel::Camelcadedb モジュールがインストールされている。
2. Apache を実行しているユーザーに PERL5_DEBUG_ROLEPERL5_DEBUG_HOSTPERL5_DEBUG_PORT の 3 つの環境変数が設定されている。
3. Apache から CGI として Perl が実行される際に、Perl が -d:Camelcadedb のオプションが付けられた状態で起動するようになっている。

  1. については特に説明しなくても大丈夫かと思います。Ubuntu14.04 (Trusty) は標準で /usr/bin/perl がインストールされていますし、cpan install Devel::Camelcadedb を実行することで Devel::Camelcadedb モジュールのインストールが行えるということは確認してきましたね。

今回の コンテナ 環境のセットアップスクリプト中では Devel::Camelcadedb がスクリプトから自動的に実行できるようにするため、Dockerfile 中に以下のように設定を記述しています。環境変数 PERL_MM_USE_DEFAULT1 に設定しておくことで、CPAN の初回起動時の設定を全て yes と入力するように自動化できます。

# cpan 自動コンフィグ
ENV PERL_MM_USE_DEFAULT 1
# Devel::Camelcadedb をインストール
RUN cpan install Devel::Camelcadedb

この時、cpan install の実行の際に makebuild-essential パッケージが必要となる点に注意して下さい。

次に 2. についてですが、今回使用している Ubuntu14.04 (Trusty) 環境では Apache は www-data というユーザが実行するようになっています。したがって、環境変数はこの www-data に対して設定されている必要があります。今回の コンテナ 環境セットアップスクリプト中ではこの設定を apache2.conf の末尾に以下のように記述しています。

apache2.conf
SetEnv PERL5_DEBUG_ROLE client
SetEnv PERL5_DEBUG_HOST 10.0.2.2
SetEnv PERL5_DEBUG_PORT 18080

これにより、Apache から CGI が起動される際にも環境変数が設定された状態となります。

最後に 3. についてはちょっと工夫が必要です。すなわち、リモートデバッグを行う際に Apache から CGI として Perl が起動される際には、前のセクションで見たように必ず -d:Camelcadedb をオプションとして設定する必要があります。Ubuntu 上で Apache が動いている場合、どのように Perl スクリプトが実行されるかは各 Perl スクリプト先頭の shebang (#!/...) に記述されている内容に依存します。したがって、そのまま shebang に #!/usr/bin/perl -d:Camelcadedb のように記述すれば良さそうですが、このように shebang を指定して CGI を実行しようとすると、ブラウザからアクセスした際に 500 Internal Server Error を吐いてしまいます。

これをどうにか回避できないかを考えました。まず初めに、Apache を実行しているユーザーにエイリアスとして alias=perl"perl -d:Camelcadedb" を設定し、CGI として Perl が実行される際にエイリアスに設定した Perl が実行されるようにできないかを考えました。現状の shebang は /usr/bin/perl のようにフルパス指定となっているため、このままではエイリアスを設定してもそのまま /usr/bin/perl を実行しようとしてしまいます。また、エイリアスにはフルパスを指定することができないことから、shebang 側をどうにか変更できないか考えました。 shebang を /usr/bin/env perl のように /usr/bin/env 経由で perl を解決するようにしておけば、問題なく実行できそうな気がしますが、Apache を実行しているユーザである www-data にたいするエイリアスを設定する方法がよく分からなかったため、この方法は断念しました。

次に、呼び出された際に /usr/bin/perl-d:Camelcadedb オプションが付加された状態で実行するシェルスクリプトを作成する方法を考えてみました。そして、結果からいえばこの方法で CGI のリモートデバッグができるようになりました。 呼び出された際に与えられた引数 (Perl のスクリプト名) をそのまま /usr/bin/perl に渡し、その際に -d:Camelcadedb オプションを付加するようにすれば問題なくリモートデバッグができそうです。そこで、以下のようなシェルスクリプトを作成してみました。

#!/bin/bash

/usr/bin/perl -d:Camelcadedb ${1} 2>/dev/null
exit 0

このシェルスクリプトは実行すると Perl インタプリタのラッパーとして振る舞い、引数として入力された Perl スクリプトの名前を /usr/bin/perl に引数 ${1} としてそのまま渡します。また、この際に -d:Camelcadedb オプションも同時に指定しています。

-d:Camelcadedb を付加した状態では、Perl スクリプトは Connected. のような IDE との接続ログ情報を標準エラー出力へと流します。CGI として動作させる上ではこの挙動は不要と考えたため、2>/dev/null と記述することで標準エラー出力を捨てています。

今回の Docker コンテナ環境では、このシェルスクリプトを /usr/local/bin/perl として配置しています。/usr/local/bin/usr/bin よりも先にチェックされるパスであるため、ただ単に perl と入力するとこちらの /usr/local/bin/perl が優先的に実行されます。これが前のセクションの最後で /usr/bin/perl -d:Camelcadedb Perlスクリプト名 のように /usr/bin/perl と Perl インタプリタをフルパスで入力しなければならないとしていた理由です。

このようにして /usr/bin/perl のラッパースクリプトを /usr/local/bin/perl に配置しておくことで、shebang を #!/usr/local/bin/perl と設定すればデバッガが有効になった状態で Perl スクリプトが実行されるため、CGI のリモートデバッグができるようになります。

(もっと賢い方法があれば教えてください...)


CGI を作成してリモートデバッグする

このようなリモートデバッグに必要な設定はリモート環境である Docker コンテナ側に既に設定されているため、CGI のデバッグに必要なことは CGI 用の Perl プロジェクトを IntelliJ IDEA 上で作成し、リモートデバッグ用の構成情報を IntelliJ IDEA に入力するだけです。

IntelliJ IDEA で新たに CGI 用の Perl プロジェクトを作成しましょう。ここでは、このプロジェクトを ~/dev/files/www/cgi-bin/IdeaPerl5 として作成しました。サンプルスクリプトを使用されている場合、既にこの Perl プロジェクトがリポジトリ中に存在しているかと思います。

次に、CGI 本体を作りましょう。ここではブラウザから自然数 $n$ を入力してもらい、$n$ 番目のフィボナッチ数を返すという単純な CGI を作ってみます。作成するファイルは、index.plresult.plFibo.pm の 3 つです。

このうち、result.pl だけはリモートデバッグ対象とするため、shebang を #!/usr/local/bin/perl に設定しておきます。

まず、index.pl は以下のようになります。

#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';

print "Content-Type: text/html; charset=utf-8\n\n";
print "<html>\n";
print "<head><title>Remote debugging sample</title></head>\n";
print "<body>\n";
print "<p>n 番目のフィボナッチ数計算</p>\n";
print "<form action='result.pl' method='post'>\n";
print "<p> n : <input type='number' name='n'></p>\n";
print "<p><input type='submit' value='Run'></p>\n";
print "</form>\n";
print "</body>\n";
print "</html>\n";
exit;

続いて、result.pl です。

#!/usr/local/bin/perl
use strict;
use warnings FATAL => 'all';
use Fibo;

my $post_data;
read (STDIN, $post_data, $ENV{'CONTENT_LENGTH'});
my $fibo = Fibo->new();
my @t = split(/=/, $post_data);
my $result = $fibo->calc_nth_fibonacci($t[1]);

print "Content-Type: text/html; charset=utf-8\n\n";
print "<html>\n";
print "<head><title>Remote debugging sample</title></head>\n";
print "<body>\n";
print "<h1>答え : $result</h1>\n";
print "</body>\n";
print "</html>\n";
exit;

最後に、Fibo.pm は以下のとおりです。

package Fibo;
use strict;
use warnings FATAL => 'all';

sub new {
    my ($class, %args) = @_;
    bless \%args, $class;
}

sub calc_nth_fibonacci {
    my $self = shift;  # 第一引数は self
    my $n = shift;     # 第二引数.

    my @table = ();

    if ($n < 1) {
        return -1;
    }

    for (my $i = 1; $i <= $n; $i++) {
        if ($i == 1 or $i == 2) {
            @table = (@table, 1);
        } else {
            @table = (@table, $table[$i - 2] + $table[$i - 3]);
        }
    }

    return $table[scalar(@table) - 1];
}

1;

ファイルが作成できたら、IntelliJ IDEA 上でリモートデバッグのための構成情報を設定しましょう。画面上部のメニューから Run -> Edit Configurations... を選択し、Run/Debug Configurations ウィンドウを表示します。

新たに Perl Remote Debugging 構成情報を作成し、以下のように構成情報を設定します。

04_リモートデバッグ001.png

前のセクションとの違いは、Remote project root で指定しているディレクトリが /www/cgi-bin/IdeaPerl5 に変更されただけです。残りの設定は前のセクションと同じ設定で大丈夫です。設定できたら OK ボタンをクリックしましょう。

後は result.pl をエディタで開き、CGI として動作している際に動作を一時的に停止させたい行にブレークポイントを設定してデバッグを開始し、ブラウザから CGI を実行すればリモートデバッグができるようになっています。

00_完成図.gif

終わりに

ここまで長い道のりでした。
わりと身内向けなネタだったのですが、誰かの開発の手助けとなれば幸いです。
最後までお読み頂きありがとうございました。

22
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
16