Solaris モジューラデバッガ

第 2 章 デバッガの概念

この章では、MDB の設計に関する重要な側面とこのアーキテクチャーの利点について説明します。

ブロックの構築

ターゲットとは、デバッガによって検査されるプログラムのことです。MDB は、現在次のターゲットをサポートしています。

各ターゲットは、プロパティーの標準セットをエクスポートします。プロパティーには、1 つまたは複数のアドレス空間、1 つまたは複数のシンボルテーブル、ロードオブジェクトセット、およびスレッドセットが含まれます。図 2–1 は、MDB アーキテクチャーの概要を示したもので、2 つの組み込みターゲットとサンプルモジュールのペアが入っています。

デバッガコマンド (MDB 用語法では、dcmd と表記し、「ディーコマンド」と読む) は、デバッガルーチンで、現ターゲットのどのプロパティーにもアクセスできます。MDB は、標準入力からコマンドを構文解析し、次に対応する dcmd を実行します。各 dcmd は、文字列や数値引数のリストも受け取ることができます (「構文」を参照)。第 5 章「組み込みコマンド」で説明しますが、MDB には、常に使用可能な組み込み dcmd セットが入っています。MDB から提供されるプログラミング API を使用して dcmd を作成することにより、プログラマは MDB そのものの機能を拡張することもできます。

walker は、特定のプログラムデータ構造体の要素を調べたり、繰り返し調べたりする方法を記述するルーチンセットです。walker は、dcmd や MDB そのものからデータ構造体の実装状態をカプセル化します。walker は、対話処理でも使用でき、ほかの dcmd や walker を構築するためのプリミティブとしても使用できます。dcmd の場合と同様に、walker を追加してデバッガモジュールの一部として実装することにより、プログラマは MDB を拡張できます。

デバッガモジュール (dmod と表記し、「ディーモッド」と読む) は、動的に読み込まれるライブラリで、一連の dcmd と walker が含まれています。初期設定の状態では、MDB は、ターゲット内に存在するロードオブジェクトに対応する dmod を読み込もうとします。その後、MDB を実行している間はいつでも、dmod の読み込みや読み込み解除ができます。MDB では、Solaris カーネルをデバッグするための標準 dmod セットが提供されています。

「マクロファイル」とは、実行するコマンドセットが入っているテキストファイルのことです。一般的に、マクロファイルは、単純データ構造体の表示プロセスを自動化するときに使用されます。MDB には下位互換性があるので、adb 言語向けに書かれたマクロファイルを実行できます。したがって、Solaris のインストールで提供されるマクロファイルセットは、新旧どちらのツールでも使用可能です。

図 2–1 MDB アーキテクチャー

この図は、MDB の構成要素 (デバッガエンジンの上にある MDB 言語と MDB モジュール API) を示しています。

モジュール性

MDB のモジューラアーキテクチャーの利点は、追加デバッガコマンドを含むモジュールを読み込む機能を拡張できることです。MDB アーキテクチャーでは、図 2–1 に示すように、各層間でインタフェースの境界を明確に定義しています。マクロファイルは、MDB や adb 言語で書かれたコマンドを実行します。デバッガモジュール内の dcmd や walker は、MDB モジュール API を使って書かれており、アプリケーションバイナリインタフェースの基礎を形成しています。このインタフェースによって、モジュールはデバッガに依存することなく展開できます。

また、walker と dcmd の MDB 名前空間は、デバッギングコード間に二次階層を定義します。このデバッギングコードは、できるかぎりコードを共有し、ターゲットプログラムそのものの展開につれて修正される必要のあるコードの数量を制限します。たとえば、Solaris カーネル内の一次データ構造体の 1 つが、システムのアクティブプロセスを示す proc_t 構造体のリストであるとします。この場合、::ps dcmd は、その出力を提示するために、このリスト検査を繰り返さなければなりません。しかし、リスト検査を繰り返すコードは ::ps 内には存在せず、genunix モジュールの proc walker 内にカプセル化されています。

MDB では、::ps dcmd と ::ptree dcmd を提供していますが、どちらの dcmd も、proc_t 構造体がカーネル内でアクセスされる方法を認識していません。その代わりに、これらの dcmd は、プログラムに従って proc walker を呼び出し、次に、戻ってきた構造体を適切にフォーマットします。また、proc_t 構造体がすでに変更されている場合には、MDB は新しい proc walker を提供するので、従属の dcmd を変更する必要はありません。さらに、::walk dcmd を使って、対話処理的に proc walker にアクセスすることもできます。そうすれば、デバッギングセッション中に新しいコマンドを作成できます。

階層化とコード共有を行うとともに、MDB モジュール API は、dcmd と walker に、単一で安定したインタフェースを提供します。このインタフェースにより、配下のターゲットのさまざまなプロパティーにもアクセスできます。これと同じ API 機能は、ユーザープロセスやカーネルターゲットからの情報にアクセスするときにも使用され、新しいデバッギング機能を開発する作業が簡単になります。

さらに、カスタム MDB モジュールを使用して、さまざまなコンテキストにおいて、デバッギングタスクを実行できます。たとえば、開発中のユーザープログラム用の MDB モジュールを開発したい場合があります。いったんその MDB モジュールを開発すると、そのモジュールを使用して、MDB は独自のプログラムの稼働中のプロセスやそのコアダンプ、あるいはプログラムを実行していたシステム上で生じたカーネルクラッシュダンプでさえも検査することができます。

モジュール API には、次のターゲットプロパティーにアクセスするための機能が提供されています。

アドレス空間

モジュール API には、ターゲットの仮想アドレス空間からデータを読み取ったり、書き込んだりする機能が用意されています。また、カーネルデバッギングモジュールには、物理アドレスを使った読み取りや書き込みの機能も提供されます。

シンボルテーブル

モジュール API には、次のものの静的シンボルテーブルおよび動的シンボルテーブルへのアクセスが用意されています。ターゲットの一次実行可能ファイル、その実行時リンカー、およびロードオブジェクトセット (ユーザープロセスではライブラリを共有し、Solaris カーネルではロード可能なモジュールとなる)。

外部データ

モジュール API には、ターゲットに関連した指定外部データバッファーの固まりを取り出す機能が用意されています。たとえば、MDB を使用すると、ユーザープロセスやユーザーコアファイルターゲットに関連した proc(4) 構造体へのアクセスが、プログラムにより可能になります。

さらに、組み込み MDB の dcmd を使用して、ターゲットメモリーマッピングに関する情報にアクセスしたり、オブジェクトを読み込んだり、値を記録したり、ユーザープロセスターゲットの実行を制御したりできます。