ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
![]() |
Oracle Solaris Studio 12.3: dbx コマンドによるデバッグ Oracle Solaris Studio 12.3 Information Library (日本語) |
より高い効果を得るにはより多くのシンボルおよびデバッグ情報が必要になる
x86 プラットフォームでは SIGSEGV シグナルと SIGALTSTACK シグナルが制限される
より高い効果を得るには、十分なパッチ領域を設け、すべての既存コードを含めて 8M バイト以内にする (SPARC プラットフォームのみ)
実行時検査には次の制限があります。
アクセス検査では、ロードオブジェクトにいくつかのシンボル情報が必要です。ロードオブジェクトが完全に削除されている場合、実行時検査ですべてのエラーをキャッチできないことがあります。初期化されていないメモリーからの読み取りエラーは正しくない可能性があるため、抑止されます。この抑止は unsuppress rui コマンドを使用して上書きできます。シンボルオブジェクトのシンボルテーブルを取得するには、ロードオブジェクトを削除する際に -x オプションを使用します。
RTC は、すべての配列範囲外エラーを検出できるわけではありません。静的メモリーおよびスタックメモリーに対する範囲検査は、デバッグ情報なしでは使用できません。
実行時検査では、メモリーアクセス命令を計測してアクセス検査をします。これらの命令は、実行時に SIGSEGV ハンドラによって処理されます。実行時検査には、独自の SIGSEGV ハンドラとシグナル代替スタックが必要なため、SIGSEGV ハンドラまたは SIGALTSTACK ハンドラをインストールしようとしても無視されるか、EINVAL エラーが生成されます。
SIGSEGV ハンドラの呼び出しは入れ子にできません。入れ子にすると、エラー terminating signal 11 SEGSEGV が生成されます。このエラーが表示された場合は、rtc skippatch コマンドを使用して、影響のある関数の計測機構を飛ばします。
既存のすべてのコードを含め、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 skippatch コマンド」を参照) を使用して、前述の関数とライブラリを使用するプログラム内のコードの計測機構を飛ばします。通常、問題を追跡して関数を特定するのは困難なため、読み込みオブジェクト全体の検査を省略する場合があります。rtc showmap コマンドにより、アドレスごとの計器タイプのマップが表示されます。
64 ビット SPARC V9 の代わりに 32 ビット SPARC V8 を使用します。
可能であれば、すべてのレジスタが 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 ファイルを追加します。
この解決方法は、プロセスの起動後に接続する場合にのみ必要です。
実行時リンカーによるライブラリの配置間隔が狭すぎてライブラリ間にパッチ領域を作成できない場合があります。RTC を on にして dbx が実行可能ファイルを起動すると、dbx は実行時リンカーに対して共有ライブラリ間に新たなギャップを挿入するよう指示しますが、実行時検査を有効にして dbx で起動されていないプロセスに接続しても、ライブラリ間が狭すぎて対応できません。
実行時ライブラリ間が狭すぎる場合 (そしてプログラムを dbx で起動できない場合) は、rtc_patch_area スクリプトで共有ライブラリを作成し、ほかの共有ライブラリ間でプログラムにリンクしてください。詳細については、rtc_patch_area(1) マニュアルページを参照してください。