CTF ライブラリ ルーチンの使用

通常は、MFTRACE_CONFIG 変数を使用して、問題のデバッグおよびコード動作の理解に役立つランタイム システム イベントを出力するように CTF を構成します。ただし、大規模なアプリケーションを開発している場合は、大まかなコード パスをトレースしたり、実行時に CTF トレーサーおよびエミッターのプロパティを変更したりするために、独自のイベントを追加する必要があることもあります。CBL_CTF_* ライブラリ ルーチンを使用すると、これが可能になります。

注: このトピックで使用されているコードは、テキスト エディターの背後にあるグラフィックス コンポーネントのサンプル アプリケーションからの抜粋です。これには、キープレス ハンドラー、グリフ シェーパー、グリフ レンダラーという 3 種類のサブコンポーネントが含まれています。例示されている抜粋は完全なプログラムを形成するものではありません。これらは、独自のプログラムに組み込むことができる特定のトレース手法を示しています。

Enterprise Developer には、CBL_CTF_* ライブラリ ルーチンを簡単に使用できるようにする構造体を含むコピーブック mfctf.cpy が用意されています。また、このアプリケーションでは、次のように定数を使用して現在のコンポーネント名を判別します。

       copy "mfctf.cpy".
       78 THIS-COMPONENT               value "GRAPHICS".

さらに、トレーサー ハンドルなどのデータを格納するために使用する次の項目が作業場所節に含まれています。ctf-trace-event-* 構造体は、カスタムのトレース イベントに関連付けられるデータを格納します。

       78  MAX-TRACE-DATA              value 5.
 
       01  ctf-event-data.
           03  ctf-tracer-handle       pic x(4) comp-5.
           03  ctf-trace-event         cblt-trc-event.
           03  ctf-trace-event-lens    pic x(4) comp-5
                                       occurs MAX-TRACE-DATA.
           03  ctf-trace-event-types   pic x(4) comp-5
                                       occurs MAX-TRACE-DATA.
           03  ctf-trace-event-ptrs    pointer
                                       occurs MAX-TRACE-DATA.

CBL_CTF_TRACER_GET ルーチンは、トレース対象のコンポーネントに対応するトレーサーを取得します。トレーサーが存在しない場合は、新しく作成されます。ls-api-flags パラメーターを使用して、トレーサー名の文字列が null で終わるか空白で終わるかを示すことができます。

       move 78-CTF-FLAG-COMP-NAME-NULL-TERM to ls-api-flags
       move THIS-COMPONENT & x"00" to ls-comp-name

       call "CBL_CTF_TRACER_GET" using
                                 by value     ls-api-flags
                                 by reference ls-comp-name
                                 by reference ctf-tracer-handle

トレーサーのプロパティは作業場所節で作成できます。これらのプロパティによって、さまざまなイベント タイプやサブコンポーネントなどを表すことができます。プロパティは、関連するトレースのオンとオフを切り替えるために使用します。

       78  PROPNAME-ALL                value "ALL"
       78  PROPNAME-EVENTS             value "EVENT_HANDLING".
       78  PROPNAME-GLYPHS             value "GLYPH_SHAPING".
       78  PROPNAME-RENDER             value "RENDERER".

作業場所節の配列 (ws-prop-name) に各プロパティの名前が含まれます。

       78  PROPNAME-ALL                value "ALL".
       78  PROPNAME-EVENTS             value "EVENT_HANDLING".
       78  PROPNAME-GLYPHS             value "GLYPH_SHAPING".
       78  PROPNAME-RENDER             value "RENDERER".

       01  ws-prop-names.
           03                          pic x(15) value PROPNAME-ALL.
           03                          pic x(15) value PROPNAME-EVENTS.
           03                          pic x(15) value PROPNAME-GLYPHS.
           03                          pic x(15) value PROPNAME-RENDER.
           03                          pic x(15) value spaces.
       01  ws-prop-name                redefines ws-prop-names
                                       pic x(15) occurs 5.

トレーサーでこれらのプロパティを作成するには、CBL_CTF_COMP_PROPERTY_GET を使用します。これにより、まだ存在しないプロパティが生成されます。この例では、ws-prop-names を反復して各プロパティを作成します。プロパティが整数値を格納することを示すために、INT-VALUE フラグが用意されています。

           move 78-CTF-FLAG-PROP-INT-VALUE to ls-api-flags

           perform varying ls-prop-id from 1 by 1
                     until ws-prop-names(ls-prop-id) = spaces

               call "CBL_CTF_COMP_PROPERTY_GET" using
                              by value     ls-api-flags
                              by reference ctf-tracer-handle
                              by reference ws-prop-name(ls-prop-id)
                              by value     0
                              by reference ls-prop-value

           end-perform

どのサブコンポーネントをトレースするかを決定するには、CBL_CTF_COMP_PROPERTY_SET で必要なプロパティを設定します。この例では、RENDERER プロパティの出力イベントを有効にしています。

           move 78-CTF-FLAG-PROP-INT-VALUE to ls-api-flags
           
           move 1 to ls-prop-value

           call "CBL_CTF_COMP_PROPERTY_SET" using
                              by value     ls-api-flags
                              by reference ctf-tracer-handle
                              by reference "RENDERER"
                              by reference ls-prop-value

プロパティが更新された際にコールバックを送信できます。これにより、プロパティをクエリするたびに CBL_CTF_COMP_PROPERTY_GET を呼び出すのではなく、現在のトレーサー プロパティおよびトレーサー レベルのビットマスクを自動的に維持できます。注:これは、動的な CTF 構成をサポートする場合にのみ必要です。

これを行うには、コールバックおよびトレーサーの詳細を保持する構造体が必要です(この構造体は、mfctf.cpy コピーブックで定義されています)。

           03  ls-install-param        cblt-trc-notif-install.

これは 0 に初期化する必要があります。その後、トレーサー ハンドルおよびコールバック関数へのポインターが構造体に配置されて、CBL_CTF_TRACER_NOTIFY でコールバックを配置できるようになります。

           move low-values to ls-install-param
           
           move ctf-tracer-handle to
                cblte-tni-handle of ls-install-param
                
           set cblte-tni-callback of ls-install-param to
               entry "ctf-tracer-notif-callback"
               
           call "CBL_CTF_TRACER_NOTIFY" using
                                        by value 0
                                        by reference ls-install-param

コールバックが書き込まれる前に、フラグが追加されます。各フラグはビットマスク内の個別のビットを占有します。ビットマスクは、ctf-trace-flags b-and TRACE_FLAGS-* を使用してすばやくクエリできます。

           78  PROPID-ALL                        value 1.
           
           78  TRACE-FLAGS-RENDERER              value h'00000001'.
           78  TRACE-FLAGS-EVENT-HANDLER         value h'00000002'.
           78  TRACE-FLAGS-GLYPH-SHAPING         value h'00000004'.
           
           
           01  ctf-config-data.
                03  ctf-trace-level         pic x(4) comp-5.
                03  ctf-trace-flags         pic x(4) comp-5 value 0.              

ビットマスクのクエリについては、イベントのトレースを開始する際の説明で再度取り上げます。

追加の構造体が必要になります。これらの構造体は、mfctf.cpy コピーブックで定義されています。

       linkage section.
       01  lk-ctf-tracer-handle        pic x(4) comp-5.
       01  lk-ctf-notif-type           pic x(4) comp-5.

       01  lk-ctf-notif-param          pic x.
       01  lk-ctf-notif-param-level    redefines lk-ctf-notif-param
                                       pic x(4) comp-5.
       01  lk-ctf-notif-param-property redefines lk-ctf-notif-param
                                       cblt-trc-notif-prop-change.
       01  lk-ctf-property-name        pic x.
       01  lk-ctf-property-value       pic x.                

コールバックにより、通知がトレーサー レベルの変更に関するものであるか、他のプロパティの変更に関するものであるかが判別されます。その後、コールバックを書き込むことができます。

通知が他のプロパティ (ALL、RENDERER、EVENT-HANDLER、GLYPH-SHAPING など) の変更に関するものである場合は、別の関数が入力されます。

           entry "ctf-tracer-notif-callback" using
                                      by value     lk-ctf-tracer-handle
                                      by value     lk-ctf-notif-type
                                      by reference lk-ctf-notif-param.
           evaluate lk-ctf-notif-type
               when 78-TRC-NOTIF-TYPE-PROP-CHANGE
                   perform ctf-tracer-notif-property

               when 78-TRC-NOTIF-TYPE-LEVEL-CHANGE
                   move lk-ctf-notif-param-level to ctf-trace-level

               when other
                    continue
           end-evaluate

           goback
           .           

どのプロパティが変更されたかを割り出すために、定義済みのプロパティ名のリストを反復して、変更されたプロパティの名前と照合します。一致するものがあった場合、新しい値が ls-prop-value 変数にコピーされ、apply-property-value が実行されます。

           ctf-tracer-notif-property section.
           set address of lk-ctf-property-name to
               cblte-tnpc-name of lk-ctf-notif-param-property

           perform varying ls-prop-id from 1 by 1
                     until ws-prop-name(ls-prop-id) = spaces


               if ws-prop-name(ls-prop-id) =
                  lk-ctf-property-name
                   (1:cblte-tnpc-namelen of lk-ctf-notif-param-property)

                   move cblte-tnpc-valint of lk-ctf-notif-param-property
                        to ls-prop-value

                   perform apply-property-value
                   exit perform
               end-if
           end-perform
           .           

これで変更されたプロパティおよびその新しい値を得られたため、それに応じてビットマスクを更新できます(特殊な場合として、ALL プロパティでは、ビットマスク全体が HIGH-VALUE に設定されます)。

           apply-property-value section.
           if ls-prop-id = PROPID-ALL
               if ls-prop-value not = 0
                  compute ctf-trace-flags = ctf-trace-flags b-or
                                            h'FFFFFFFF'
               else
                  move 0 to ctf-trace-flags
               end-if
           else
               compute ls-work-var = 2 ** (ls-prop-id - 2)

               if ls-prop-value not = 0
                   compute ctf-trace-flags = ctf-trace-flags b-or
                                             ls-work-var
               else
                   compute ctf-trace-flags = ctf-trace-flags b-and b-not
                                             ls-work-var
               end-if
           end-if
           .

「event level」は、イベントの重要度を示すために使用します。「tracer level」(MFTRACE_CONFIG 内) を設定すると、イベントをトレースするために最低限必要な重要度が決まります。指定できるトレーサー レベルは、INFOWARNINGERROR、および FATAL です。

動的な CTF 構成が必要ない場合は、プログラムの開始時に CBL_CTF_TRACER_LEVEL_GET および CBL_CTF_COMP_PROPERTY_GET を使用してトレーサー プロパティを単に取得します。次に例を示します。

           move 78-CTF-FLAG-PROP-INT-VALUE to ls-api-flags

           move 1 to ls-prop-id

           call "CBL_CTF_COMP_PROPERTY_GET" using
                              by value     ls-api-flags
                              by reference ctf-tracer-handle
                              by reference ws-prop-name(ls-prop-id)
                              by value     0
                              by reference ls-prop-value                             

および

           move 0 to ls-api-flags

           call "CBL_CTF_TRACER_LEVEL_GET" using
                                       by value     ls-api-flags
                                       by reference ctf-tracer-handle
                                       by reference ctf-trace-level

この時点で、トレース イベントを生成できます。レンダラー イベントを作成できます。これは、RENDERER プロパティまたは ALL プロパティが設定されている場合にのみトレースされます。また、このイベントは、トレーサー レベルが INFO 以下の場合にのみ表示されます (つまり、この特定のトレース イベントはそれほど重要ではなく、プログラムの動作に関する一般的な情報を提供するだけです)。イベント ID を表すために次の定数を作成できます。

           78  EVENT-RENDERER-DRAW      value 0
           78  EVENT-GLYPH-SHAPE        value 1
           78  EVENT-EVENT-HANDLED      value 2

これらの定数により、ビットマスクをクエリして、RENDERER プロパティが設定されているかどうか、および現在のトレーサー レベルが INFO 以下であるかどうかを確認できます。両方のクエリが true の場合、イベントを作成してトレーサーに送信できます(次の例では、このトピックの冒頭に示されている ctf-event-data 構造体を使用します)。

           if (TRACE-FLAGS-RENDERER b-and ctf-trace-flags) not = 0
           and 78-CTF-FLAG-LEVEL-INFO >= ctf-trace-level
               move EVENT-RENDERER-DRAW to ls-trace-event
               move 78-CTF-FLAG-LEVEL-INFO to ls-trace-level
               perform trace-event
           end-if           

イベントを作成すると、イベント名およびレベルが ctf-trace-event 構造体に格納されます。evaluate 文を使用して、たとえば変数に格納された値などの追加データをイベントに読み込むために、特定の関数を呼び出すことができます。次の例では、GLYPH-SHAPE イベントは処理対象のテキストを出力します。RENDERER-DRAW イベントには追加データが必要ないので、そのためのヘルパー関数はありません。ls-trace-data-count をデフォルト値の 0 のままにしておきます。

           trace-event section.
           move 78-TRACE-EVENT-FLAGS-NONE to
                cblte-trcevt-flags of ctf-trace-event
           move ls-trace-event to
                cblte-trcevt-event-id of ctf-trace-event
           move ls-trace-level to
                cblte-trcevt-level of ctf-trace-event

           move 0 to ls-trace-data-count

           evaluate ls-trace-event
               
               when EVENT-GLYPH-SHAPE
                   perform trace-event-glyph-shape

               when EVENT-RENDERER-DRAW
               ...
                   continue
           end-evaluate

           move ls-trace-data-count to
                cblte-trcevt-data-count of ctf-trace-event

           call "CBL_CTF_TRACE" using by value     0
                                      by reference ctf-tracer-handle
                                      by reference ctf-trace-event

           end-if
           .           

一部のデータを含むトレース イベントでは、ヘルパー関数を呼び出して変数を設定できます。前述の ctf-event-data 構造体は、MAX-TRACE-DATA の値まで格納できます。この例では、イベントごとに最大 5 つの追加データ項目を使用できることになります。トレーサーでは、提供されているデータの種類 (ctf-trace-event-types) およびそのサイズ (ctf-trace-event-lens) を把握する必要があります。

           03  ls-trace-data-desc      pic x(40).
           
           
           trace-event-glyph-shape section.
           
           move "Blah blah blah" to ls-trace-data-desc

           set ctf-trace-event-ptrs(1) to 
               address of ls-trace-data-desc

           move 14 to ctf-trace-event-lens(1)

           move 78-TRACE-EVENT-TYPE-TEXT to
                ctf-trace-event-types(1)

           add 1 to ls-trace-data-count
           .           

これでイベントが設定されたため、trace-event-glyph-shape 関数が返され、CBL_CTF_TRACE の呼び出しによってコンポーネントのトレーサーにイベントが送信されます。トレーサーから有効なエミッターにデータが送信され、エミッターからディスク上のファイルにトレース イベントが出力されます。