Oracle® Developer Studio 12.5: dbx コマンドによるデバッグ

印刷ビューの終了

更新: 2016 年 6 月
 
 

実行時検査の制限

このセクションでは、実行時検査の制限について説明します。

シンボルやデバッグ情報が多いほどパフォーマンスが向上する

アクセス検査では、ロードオブジェクトにいくつかのシンボル情報が必要です。ロードオブジェクトが完全に削除されている場合、実行時検査ですべてのエラーをキャッチできないことがあります。「非初期化領域からの読み取り」(rui) メモリーエラーは正しくないことがあるため、抑制されます。この抑止は unsuppress rui コマンドを使用してオーバーライドできます。ロードオブジェクト内のシンボルテーブルを保持するには、ロードオブジェクトのストリップ時に –x オプションを使用します。

RTC は、すべての配列範囲外エラーを検出できるわけではありません。静的メモリーおよびスタックメモリーに対する範囲検査は、デバッグ情報なしでは使用できません。

x86 プラットフォームでは SIGSEGV シグナルと SIGALTSTACK シグナルが制限される

実行時検査では、メモリーアクセス命令を計測してアクセス検査をします。これらの命令は、実行時に SIGSEGV ハンドラによって処理されます。実行時検査には独自の SIGSEGV ハンドラとシグナル代替スタックが必要なため、SIGSEGV ハンドラまたは SIGALTSTACK ハンドラをインストールしようとすると、EINVAL エラーが発生するか、またはその試みが無視されます。

SIGSEGV ハンドラの呼び出しは入れ子にできません。入れ子にすると、エラー terminating signal 11 SEGSEGV が生成されます。このエラーが表示された場合は、rtc skippatch コマンドを使用して、影響のある関数の計測機構を飛ばします。

既存のすべてのコードから 8M バイト以内で十分なパッチ領域が使用可能な場合はパフォーマンスが向上する (SPARC プラットフォームのみ)。

    既存のすべてのコードから 8M バイト以内で十分なパッチ領域が使用できない場合は、2 つの問題が発生する可能性があります。

  • 遅延

    アクセス検査が有効になっている場合、dbx は、各ロードおよびストア命令をパッチ領域に分岐する分岐命令に置き換えます。この分岐命令には 8M バイトの範囲があります。デバッグ対象プログラムが、置き換えられている特定のロードまたはストア命令から 8M バイト以内のアドレス空間のすべてを使用していると、パッチ領域を配置するための場所は存在しません。この場合、dbx は分岐を使用する代わりにトラップハンドラを呼び出します。トラップハンドラへの制御の移行は大幅に (最大 10 倍) 遅くなりますが、8M バイトの制限は存在しなくなります。

  • V8+ モードでの出力レジスタのオーバーライドの問題

    トラップハンドラの制限は、次の両方の状況に該当する場合に、アクセス検査に影響します。

    • デバッグするプロセスがトラップを使用して検査される。

    • プロセスが V8+ 命令セットを使用する。

    この問題は、V8+ アーキテクチャーでの出力レジスタのサイズと入力レジスタのサイズが異なるために発生します。出力レジスタは 64 ビット長ですが、入力レジスタは 32 ビット長しかありません。トラップハンドラが呼び出されると、出力レジスタが入力レジスタにコピーされ、上位 32 ビットが失われます。そのため、デバッグ対象のプロセスが出力レジスタの上位 32 ビットを使用している場合は、アクセス検査が有効になっていると、そのプロセスが誤って実行される可能性があります。

    コンパイラは、32 ビット SPARC ベースのバイナリの作成時にデフォルトでは V8+ アーキテクチャーを使用しますが、–xarch オプションを指定して、コンパイラに V8 アーキテクチャーを使用するよう指示することができます。アプリケーションを再コンパイルしてもシステム実行時ライブラリは影響を受けません。

      dbx は、トラップとともに計測されると正しく機能しないことがわかっている次の関数およびライブラリの計測機構を自動的にスキップします。

    • server/libjvm.so

    • client/libjvm.so

    • `libfsu_isa.so`__f_cvt_real

    • `libfsu_isa.so`__f90_slw_c4

    ただし、計測機構を飛ばすと、不正な RTC エラーが生成されることがあります。

使用しているプログラムに上のいずれかの条件が当てはまり、かつアクセス検査を有効にしたときにプログラムが異なる動作を始める場合は、トラップハンドラの制限がそのプログラムに影響を与えている可能性があります。この制限を回避するには、次の操作を実行します。

  • rtc skippatch コマンドを使用して、上に示されている関数およびライブラリを使用しているプログラム内のコードの計測機構をスキップします。一般に、問題を特定の関数まで追跡することは困難であるため、ロードオブジェクト全体の計測機構をスキップすることもできます。rtc showmap コマンドによって、アドレスでソートされた計測タイプのマップが表示されます。

  • 32 ビット SPARC-V8 の代わりに 64 ビット SPARC-V9 を使用してみてください。

    可能であれば、すべてのレジスタが 64 ビット長の V9 アーキテクチャーでプログラムを再コンパイルします。

  • パッチ領域オブジェクトファイルを追加します。

    rtc_patch_area シェルスクリプトを使用し、大きな実行可能ファイルや共有ライブラリの中間にリンクできる特別な .o ファイルを作成すれば、パッチ領域を拡大できます。詳細については、rtc_patch_area(1) のマニュアルページを参照してください。

    dbx は 8M バイトの制限に達すると、どのロードオブジェクトが大きすぎたかをユーザーに示し (メインプログラムまたは共有ライブラリ)、そのロードオブジェクトに必要な合計パッチ領域を表示します。

    最適な結果を得るには、実行可能ファイルや共有ライブラリ全体に特別なパッチオブジェクトファイルを均等に分散させ、デフォルトサイズ (8M バイト) かそれよりも小さいサイズを使用します。dbx が必要とする必要値の 10 % から 20 % の範囲を超えてパッチ領域を追加しないでください。たとえば、dbx が a.out に 31M バイトを要求する場合は、rtc_patch_area スクリプトで作成した 8M バイトのオブジェクトファイルを 4 つ追加し、実行可能ファイル内でそれらをほぼ均等に分割します。

    dbx の実行時に、実行可能ファイルに明示的なパッチ領域が見つかると、パッチ領域になっているアドレス範囲が出力されるので、リンク回線に正しく指定することができます。

  • 読み込みオブジェクトが大きい場合は、小さい読み込みオブジェクトに分割します。

    実行可能ファイルまたは大きなライブラリ内のオブジェクトファイルをより小さいオブジェクトファイルのグループに分割してから、それらをより小さい部分にリンクします。大きなファイルが実行可能ファイルである場合は、それをより小さい実行可能ファイルと一連の共有ライブラリに分割します。大きいファイルが共有ライブラリの場合、複数の小さいライブラリのセットに再編します。

    この方法により、dbx は、さまざまな共有オブジェクトの間にパッチコード用の領域を見つけることができます。

  • パッド .so ファイルを追加します。

    この解決方法は、プロセスの起動後に接続する場合にのみ必要です。

    実行時リンカーによるライブラリの配置間隔が狭すぎてライブラリ間にパッチ領域を作成できない場合があります。dbx は、実行時検査が有効になった状態で実行可能ファイルを起動する場合、共有ライブラリ間に余分な間隔を空けるよう実行時リンカーに依頼します。ただし、実行時検査が有効になった状態で dbx が起動していないプロセスに接続する場合は、各ライブラリが近づきすぎている可能性があります。

    実行時ライブラリが近づきすぎており、かつ dbx を使用してプログラムを起動できない場合は、rtc_patch_area スクリプトを使用して共有ライブラリを作成し、それをほかの共有ライブラリの間にあるプログラムにリンクしてみることができます。詳細については、rtc_patch_area(1) のマニュアルページを参照してください。