連載20-ローダー機能ー4
前回までで、ロードモジュールをロードし実行するまでを行いました。
今回は、いくつかの開発スタイルにおいてどのようにデバッグをするのか、についてご紹介できればと思います。
1.開発スタイルとデバッグ対象
今回、開発のスタイルについて、以下3パターンを考えてみます。
・メインアプリのワークスペースを使って、メインアプリ&ロードモジュールのデバッグをする
デバッグする人はメインアプリ担当者であるケースです。
・ロードモジュールのワークスペースを使って、メインアプリ&ロードモジュールのデバッグをする
デバッグする人はロードモジュール担当者であるケースです。
かつ、メインアプリのソースコードも入手できる場合です。
・ロードモジュールのワークスペースを使って、ロードモジュールのデバッグだけをする
デバッグする人はロードモジュール担当者であるケースです。
メインアプリのソースコードは入手できない場合です。
ロード機能を使わない場合ももちろんありますが、ここでは、
「ロード機能を使って開発する場合」
と限定します。
2.デバッグ
では早速試してみましょう。
今回も、Cortex-A9搭載ボード×PARTNER Jet2の組み合わせを使用します。
ロードモジュールはDLL形式で行います。
18回で作成したメインアプリ&DLLアプリを使用します。
SOLID独自形式とDLL形式では、ロードしシンボル解決する方法は違いますが、その後はどちらも変わりありません。
2.1 メインアプリのワークスペースでメインアプリ&ロードモジュールのデバッグをする
メインアプリのワークスペースを起動します。
以下の箇所でDLL内の関数をコールするため、一旦ブレークを設定しておき、実行を行い、以下のブレークポイントで一旦停止させてみます。
この状態で、ステップインすると、飛び先のDLLのソースコードが表示されます。
さらにステップすると、DLLの内関数のローカル変数も見ることができます。
ちなみに、DLLのソースコードが、ビルドした際の場所にない場合は、ソースファイルの場所を問い合わせするダイアログボックスが表示されます。
2.2 ロードモジュールのワークスペースでメインアプリ&ロードモジュールのデバッグをする
まず、ロードモジュールであるDLLのワークスペースを起動します。
ブレークの設定を可能とするために、設定を行う必要があります。
プロジェクトのプロパティを開きます。
エントリポイントを、solid_startとします。
MMUの設定が完了しているポイントです。
これで、MMUの設定完了後であるエントリポイントに到達してからソフトウェアブレーク(ブレークポイント)を設定する仕組みになります。
では次に、メインアプリのソースコードと、DLLのソースコードへブレークを設定してみましょう。
今、この状態では、メインアプリのソースコードも同じPC上に存在します。
そしてそれは、ビルドした時のパスから変更していません。
なので、少々雑ですが、直接開いてしまいましょう。
メインアプリのsample1.cを開きます。
そして、ソースコードの左端をクリックして、ブレークポイントを設定します。
次に、DLLのソースコードにもブレークポイントを設定します。
では実行してみます。
まず、メインアプリでブレークしました。
ローカル変数も見えていますね。
dll.cに設定したブレークポイントは、白抜きの赤丸になっていますので、まだ設定ができていない状態です。
これは当然ですね。
今、ブレークしているところは、まだこのDLLロードしていませんから。
SOLID_LDR_LoadDLL関数は、少し先にありますね。
では、この状態で、実行してみましょう。
無事、DLL内関数のブレークポイントでブレークしました。
ローカル変数も見えていますし、DLL内のデバッグもできますね。
ちなみに、PC内にメインアプリのソースコードがあっても、ビルドしたパスと違う場所にある場合でも大丈夫です。
DLLロード時にソースファイルの場所を問い合わせするダイアログボックスが開くので、その際にIDEに正しいパスを教えることができます。
2.3 ロードモジュールのワークスペースでメインアプリ&ロードモジュールのデバッグをする
この場合は、メインアプリのソースコードがない状態、と理解することができます。
ロードモジュールのワークスペースを起動し、プロパティの設定を2.1で設定した内容と同じにします。
この状態で、DLLにのみブレークを設定してみます。
実行すると、DLL内関数でブレークが発生します。
メインアプリのことを全く気にせず、DLLのデバッグができますね。
3.SOLIDで分散開発
以上、すべてのケースで、必要なデバッグができることがわかりました。
どうも分散開発というのは、ここのデバッグする場合はこのバッチファイルを流して、、、等、開発上の手順があって、一つでも間違うと動かないし、、、
で、結局面倒で、結局秘密保持契約結んでソース一式提供する、という経験が多いものですから(筆者だけかもしれませんが)、あまり分散できていないイメージがありました。
でもSOLIDのロード機能を使えば、すごく操作が単純化されているので、間違ったり迷ったりすることがないのが良いですね。
加えて、実際の体験談なのですが、もう一つの大きなメリットもお伝えしておきたいと思います。
製品を開発していると、ソースコードが数千個にもなってしまう場合があります。
結果、リンクするだけで10分以上かかるようです。
これ、頻繁にやりたくないですよね?
そんな時、初めからローダー構造を採用していれば、自分に係わるところだけコンパイルリンクするだけでOKです。
無駄な時間も減らせるし、「ちょっとコードを書き換えて試す」みたいなスタイルで開発を回せて、SOLID 的 "Enjoy Development" だと思いませんか?
4.補足:開発スタイル
開発のスタイルについてもう少し。
具体例とともに補足します。
4.1 一つのチームで全体を開発する(1)
まず、一つのチームで全体を開発するスタイルの場合。
基幹部であるメインアプリを開発し、各ロードモジュールも自分達で開発する場合です。
下の図で言うと、基幹部もアプリA,B,Cもすべて自分達で開発します。
この場合、ワークスペースは以下存在します。
メインアプリ用ワークスペース
アプリA用ワークスペース(ロードモジュール)
アプリB用ワークスペース(ロードモジュール)
アプリC用ワークスペース(ロードモジュール)
それぞれのワークスペースでビルドを行い、バイナリを生成します。
では、デバッグについて考えてみましょう。
基幹部もアプリA,B,Cもすべて自分達で開発しているため、すべてのワークスペースが手元にあります。
一番考えやすいのは、メインアプリのワークスペースを用いてデバッグをする、ことですね。
前回までで、メインアプリから各ロードモジュールをロードし、実行することができました。
これは、
「メインアプリのワークスペースを使って、メインアプリ&ロードモジュールのデバッグをする」
です。
4.2 一つのチームで全体を開発する(2)
一つのチームで全体を開発するスタイルの場合の別パターンです。
例えば、
「アプリAの動きがおかしいなぁ。トライ&エラーでデバッグしたいなぁ」の場合。
この場合は、
「アプリAのワークスペースを使って、アプリAのデバッグをする。
アプリAソースコードを変更しビルド、ロードし実行。
またソースコードを変更しビルド、ロードし実行。。。(繰り返す)
メインアプリに返される値も見たい。」
というデバッグになります。
これは、
「ロードモジュールのワークスペースを使って、メインアプリ&ロードモジュールのデバッグをする」
となります。
4.3 チームが複数である場合
次に、開発チームが複数である場合について考えてみます。
例えば、以下の場合。
・自社で基幹部となるメインアプリを開発
・協力会社で各ロードモジュールを開発
下の図で言うと、例えば
基幹部は自分達
アプリAはA社
アプリBはB社
アプリCはC社
という分担です
この場合も、ワークスペースは以下存在します。
メインアプリ用ワークスペース
アプリA用ワークスペース(ロードモジュール)
アプリB用ワークスペース(ロードモジュール)
アプリC用ワークスペース(ロードモジュール)
先程と同様、それぞれのワークスペースでビルドを行い、バイナリを生成します。
デバッグについて考えてみましょう。
メインアプリ開発部隊は、ロードモジュールのデバッグは不要、ロードモジュールはバイナリだけでOKです。メインアプリ部だけデバッグできれば良いです。
アプリA開発部隊は、メインアプリ部のデバッグは不要で、メインアプリ部はバイナリだけでOKです。アプリAだけデバッグできれば良いです。
これは
「ロードモジュールのワークスペースを使って、ロードモジュールのデバッグだけをする」
となります。
以上、補足でした。
5.まとめ
4回にわたりロード機能をご紹介してきました。
筆者としては、組み込みでDLLを扱うという発想がなかったので、なんだか新鮮な気分でした。
今回DLL内でのブレークをご紹介しましたが、こうやってメインアプリと完全に独立してDLL部の開発ができる仕組みがあることで、分散開発をきれいな形で行え、結果、保守性も高まるのではと思いました。
さて、ロード機能は今回で終了です。
次回は、QMUによるシミュレーションを行う予定です。