System4.0 Tips

前編

System4.0のデバッグ時の変数表示を自作してみた

 

こんな感じ です。

イメージ的には、VisualStudioのクイックウォッチ+データヒント。

実行には .net framework2.0 が必要です。

 

DPQuickShow をダウンロード

 

以下は、注意が必要な箇所などのメモ


後編

System4.0でDebugPlugin (メモ)

メモです。あまり丁寧ではありません。

 

DebugPluginとは?

 Debug実行時に使用可能なPluginです。
具体的には、コンパイル時に生成される「debug.jad」「debug2.jad」が存在している場合に、
DPフォルダに「~.ade」のファイルがDebugPluginとして認識されます。

 認識されたDebugPluginは、System4.0のメニューに「デバッグプラグイン」として表示されます。
標準では以下の5個のDebugPluginが認識されています。

標準認識されるDebugPlugin [ 解析、ログビューア、SACT、文字列、変数 ]

 

作成方法

 DebugPluginは自作することが可能です。
作成するためには、C++が必要となります。

[ Sys42SDK_20041224\熟練者向けセット\DLL開発\開発キット\DP ]
に、C++用のヘッダと、サンプルが存在します。

 IJaffaDebugPlugin を継承したPluginとなるクラスを作成し、
そのインスタンスを、System4.0から呼び出されるCreatePlugin で戻り値として返します。

 Initは初期化。Openは開くコマンド時、Closeは閉じるコマンド時(?)、
GetNameはSystem4.0のメニューに表示する名前を返します。

 少なくとも、ここまでで一度コンパイルし、メニューに登録されることを確認してください。
拡張子をadeにして、DPフォルダにコピーすれば、自動的に認識されます。

 

ウィンドウ表示

 ウィンドウ表示の方法はいろいろあると思いますが、
MFCとCLR(マネージ拡張)について確認しました。

 MFCを用いる場合は AFX_MANAGE_STATE でマクロをかましてやる必要があります。

 CLR(C++/CLI : VC2005)を用いる場合は、
COMの初期化に失敗するので (  =>原因
初期化時にマネージコードを一回実行し、直後にCoUninitializeを実行することで解決します。
また、ネイティブコードからマネージコードを実行することになるのでフォームクラスにgcrootを
かぶせてあげる必要があります。

 

Debug関連のInterface取得

  [ Sys42SDK_20041224\熟練者向けセット\DLL開発\マニュアル\IVMDebugの取得方法.txt ] に書いてあります。
うぃんすろうさんのところの、GetSys4IFを用いて、、、

< Init関数内 >

pIMainSystem=(IMainSystem*)pIJaffaDebug->GetInterface(&IID_IMainSystem);

pISys40Ini=(ISys40Ini*)pIMainSystem->GetInterface(&IID_ISys40Ini);

char* vmn=pISys40Ini->GetMainVMName();

pIVMDebug=(IVMDebug*)GetSys4IF(pIVMDebug=NULL,vmn,"GetDebugInterface",&IID_IVMDebug);

pIVMDebugPage=(IVMDebugPage2*)GetSys4IF(pIVMDebugPage=NULL,vmn,"GetDebugInterface",&IID_IVMDebugPage2);

pIVMDebugJabFile=(IVMDebugJabFile*)GetSys4IF(pIVMDebugJabFile=NULL,vmn,"GetDebugInterface",&IID_IVMDebugJabFile);

pIVM=(IVM*)GetSys4IF(pIVM=NULL,vmn,"GetInterface",&IID_IVM);

 IVMGlobalはGetDebugInterfaceで取得できるハズと考えてますが取得できません。
GetInterfaceで取得すると、IVMと同じアドレスが返ってきました。謎です。
 

 

IVMDebugPage

 ページとは、関数とかの内部の変数群のこと。
グローバル領域、関数内変数、構造体(クラス)、配列、文字列がそれぞれのページとなる。

functypeはポインタ(関数番号)が入っている。定数は含まれない。(ページ/変数ともに)
文字列は、ポインタ(ページ番号)が入っている。
構造体もポインタが入っている(ページ番号)
配列も、ポインタ(ページ番号)。

Type=-1:NULL
Type=0:グローバル
Type=1:関数
Type=2:文字列
Type=3:配列
Type=4:構造体
関数一個つむごとに1つ増える。関数を消すと、Type=-1
 

変数の名前を取得するのは、うまいことIVMDebugJabFileとの整合性を取る必要がありそう。
 

ページの中身は、基本的に4byte区切り。
32bitのInt、32bitのfloat、32bitのポインタ(このポインタは、ページへのポインタ、あるいは関数/構造体番号)

ただし、参照変数の場合は、8byte使用する。(格納は4byte+4byteとなる)
この場合、変数名は、"name","<void>" で格納される。
それぞれの内容は、参照先ページポインタ、ページ内の参照先 が入る。

 

 

 

 

 感想

  大変でした。いやほんとに。
 これだけ足跡残してあれば、同じようなことをやろうとする人は楽ちんですね。
 いないと思うけど。
 サンプルは、DPQuickShowのを使用してください。