C/400

46. デバッグ・モードの検出

現在のプログラムがデバッグ・モードとして実行されていることを検出することは意外と難しい。
デバッグ・モードで SEU を開くと「デバッグ中である」とのメッセージが表示されることは
良く知られているが SEU は、どのようにして今、デバッグ・モードで実行されているのかを
検知しているのだろうか ?
RTVJOBA や INFDS や DSPJOB にもデバッグに関する情報はないのである。
IBM マニュアルを探してもこの方法は解説されていない。
ここでは API : QteRetrieveDebugAttribute (デバッグの属性の取得) による方法を紹介する。
API : QteRetrieveDebugAttribute をデバッグ中ではないときに実行すると
API エラーとして CPF9541 : デバッグ・モードになっていない とのエラーが戻ってくる。
このことを利用してデバッグ中であるかどうかを判断することができるのである。

【 サンプル 】
0001.00 #include <stdio.h>                                              
0002.00 #include <stdlib.h>                                             
0003.00 #include <string.h>                                             
0004.00 #include <QTEDBGS.h>                                            
0005.00                                                                 
0006.00 #define TRUE         0                                          
0007.00 #define FALSE       -1                                          
0008.00 int IsDebugMode(void);                                          
0009.00                                                                 
0010.00 void main(void){                                                
0011.00    char buff[128];                                              
0012.00                                                                 
0013.00    printf("** TESTDBG **\n");                                   
0014.00    getchar();                                                   
0015.00     if(IsDebugMode() == TRUE) printf("on Debug Mode\n");        
0016.00     else printf("Release Mode\n");                              
0017.00     getchar();                                                  
0018.00 }                                                               
0019.00 /********************/                                          
0020.00 int IsDebugMode(void)                                           
0021.00 /********************/                                                 
0022.00 {                                                                      
0023.00   _TE_ERROR_CODE_T errorCode;                                          
0024.00   char attr[10];                                                       
0025.00                                                                        
0026.00    errorCode.BytesProvided  = sizeof(errorCode);                       
0027.00    errorCode.BytesAvailable = 0;                                       
0028.00    QteRetrieveDebugAttribute("*DEBUGJOB ", attr, &errorCode);          
0029.00    if(errorCode.BytesAvailable != 0){/* APIERR */                      
0030.00      if(strncmp(errorCode.ExceptionID, "CPF9541", 7) == 0) return FALSE
0031.00     else return TRUE;                                                  
0032.00    }/* APIERR */                                                       
0033.00    else return TRUE;                                                   
0034.00 }                                                                      
【 解説 】
0028.00    QteRetrieveDebugAttribute("*DEBUGJOB ", attr, &errorCode);

によって QteRetrieveDebugAttribute を実行して APIERR コード errorCode の MSGID が
CPF9541 かどうかを判断している。
デバッグ・モードかどうかの判断が、どのように役に立つのかと思われるか知れないが
eStudio のデバッガーを開発するのには非常に重要であった。
eStudio は Webベースの IDE環境上で Web適用業務のデバッグを可能にしなければならない。
Web適用業務はステーレトスであるので一度でも HTMLを出力してしまうと CGI はLR終了する。
これを連続してデバッグが可能なようにしなければならない。

eStudio でデバッグを指示すると CGI を直接、起動するのではなく eStudio が指定する
デバッガーを呼び出して、パラメータとして CGI の名前とライブラリー名を
デバッガーに与える。
デバッガーは STRDBG コマンドを起動して 指定された CGI を実行する。
CGI の出力結果はもちろん HTML としてブラウザに出力されるのだが
次に出力された HTML のボタン等を押して、次の処理の連続を試みると
前の CGI は、HTML を出力と同時に終了しているのでデバッグを継続することはできない。
つまりリリース・モードで実行されてしまう。
そこで RPGエンジンは 上記の API : QteRetrieveDebugAttribute によってデバッグモードで
実行中であると判断すると 出力する HTML の SUBMIT 記述を CGI ではなくデバッガーに渡すように
変更するのである。
このことによって次の操作でも再びデバッガーに処理は投入されてデバッグを継続することができる。
このように高度なデバッガーを開発しようとすると、実行中のジョブがデバッグモードであるかの
判断が必要になるのである。