Solaris モジューラデバッガ

API 関数

mdb_pwalk()

int mdb_pwalk(const char *name, mdb_walk_cb_t func, void *data,
              uintptr_t addr);

name で指定された walker を使用して addr から始まる局所 walk を開始し、各ステップでコールバック関数 func を呼び出します。addr が NULL の場合、大域 walk が実行されます。mdb_pwalk() を呼び出すことは addr パラメータを追跡せずに mdb_walk() を呼び出すことと同じです。この関数は成功すると 0 を返し、エラーが発生すると -1 を返します。walker 自体が致命的なエラーを返した場合、または指定された walker 名がデバッガに認識されない場合、mdb_pwalk() 関数は失敗します。walker 名に重複があった場合、逆引用符 (`) 演算子を使用して名前の有効範囲を指定できます。data パラメータは、呼び出し元にだけ意味を持つ隠された引数です。このパラメータは walk の各ステップで func に戻されます。

mdb_walk()

int mdb_walk(const char *name, mdb_walk_cb_t func, void *data);

name で指定された walker を使用して addr から始まる大域 walk を開始し、各ステップでコールバック関数 func を起動します。この関数は成功すると 0 を返し、エラーが発生すると -1 を返します。walker 自体が致命的なエラーを返した場合、または指定された walker 名がデバッガに認識されない場合、mdb_walk() 関数は失敗します。walker 名に重複があった場合、逆引用符 (`) 演算子を使用して名前の有効範囲を指定できます。data パラメータは、呼び出し元にだけ意味を持つ隠された引数です。このパラメータは walk の各ステップで func に戻されます。

mdb_pwalk_dcmd()

int mdb_pwalk_dcmd(const char *wname, const char *dcname, int argc,
			const mdb_arg_t *argv, uintptr_t addr);

wname で指定された walker を使用して addr から始まる局所 walk を開始し、各ステップで argc および argv を指定して、dcname で指定された dcmd を起動します。この関数は成功すると 0 を返し、エラーが発生すると -1 を返します。walker 自体が致命的なエラーを返した場合、指定された walker 名または dcmd 名がデバッガに認識されない場合、あるいは dcmd 自体が walker に DCMD_ABORT または DCMD_USAGE を返した場合、この関数は失敗します。名前の重複があった場合、walker 名と dcmd 名は逆引用符 (`) 演算子を使用して名前の有効範囲を指定できます。mdb_pwalk_dcmd() から起動された場合、dcmd の flags パラメータには DCMD_LOOP および DCMD_ADDRSPEC ビットが設定され、最初の呼び出しでは DCMD_LOOPFIRST が設定されます。

mdb_walk_dcmd()

int mdb_walk_dcmd(const char *wname, const char *dcname, int argc,
			const mdb_arg_t *argv);

wname で指定された walker を使用して大域 walk を開始し、各ステップで argc および argv を指定して、dcname で指定された dcmd を起動します。この関数は成功すると 0 を返し、エラーが発生すると -1 を返します。walker 自体が致命的なエラーを返した場合、指定された walker 名または dcmd 名がデバッガに認識されない場合、あるいは dcmd 自体が walker に DCMD_ABORT または DCMD_USAGE を返した場合、この関数は失敗します。名前の重複があった場合、walker 名と dcmd 名は逆引用符 (`) 演算子を使用して名前の有効範囲を指定できます。mdb_walk_dcmd() から起動された場合、dcmd の flags パラメータには DCMD_LOOP および DCMD_ADDRSPEC ビットが設定され、最初の呼び出しでは DCMD_LOOPFIRST が設定されます。

mdb_call_dcmd()

int mdb_call_dcmd(const char *name, uintptr_t addr, uint_t flags, 
			int argc, const mdb_arg_t *argv);

与えられたパラメータで指定された dcmd 名を起動します。ドット変数が addr にリセットされ、addrflagsargc、および argv が dcmd に渡されます。この関数は成功すると 0 を返し、エラーが発生すると -1 を返します。dcmd が DCMD_ERRDCMD_ABORT、または DCMD_USAGE を返した場合、あるいは指定された dcmd 名がデバッガに認識されない場合、この関数は失敗します。名前の重複があった場合、dcmd 名は逆引用符 (`) 演算子を使用して名前の有効範囲を指定できます。

mdb_layered_walk()

int mdb_layered_walk(const char *name, mdb_walk_state_t *wsp);

wsp で指定された walk を、指定された walker 名を使用して開始された walk の上の層に置きます。名前の重複があった場合、dcmd 名は逆引用符 (`) 演算子を使用して名前の有効範囲を指定できます。階層化された walk を使用すると、ほかのデータ構造体に組み込まれたデータ構造体に対する walker を簡単に作成することができます。

たとえば、カーネルの各 CPU 構造体に組み込み構造体を指すポインタが含まれているとします。組み込み構造体タイプに対する walker を作成するときに、CPU 構造体を繰り返すコードを複製して各 CPU 構造体の該当するメンバーの参照を解除する、あるいは組み込み構造体の walker を既存の CPU walker の上に重ねることができます。

mdb_layered_walk() 関数は、現在の walk に新規の層を追加するために walker の init ルーチンの中から使用されます。配下の層は mdb_layered_walk() の呼び出しの一部として初期化されます。呼び出し元の walk ルーチンは、現在の walk の状態を指すポインタを渡します。この状態を使用して階層化された walk が構築されます。階層化された各 walk は、呼び出し元の walk fini 関数が呼び出されたあと、クリーンアップされます。複数の層が walk に追加されている場合、呼び出し元の walk step 関数は最初の層から返された各要素を処理したあと、次に 2 番目の層へ進み、以降も同様に処理します。

mdb_layered_walk() 関数は成功した場合 0 を、エラーの場合 -1 を返します。指定された walker 名がデバッガに認識されない場合、wsp ポインタが有効かつアクティブな walk 状態ポインタでない場合、階層化された walker 自体が初期化に失敗した場合、または呼び出し元が自分自身の上に walker を重ねようとした場合、この関数は失敗します。

mdb_add_walker()

int mdb_add_walker(const mdb_walker_t *w);

新規の walker をデバッガに登録します。walker は、「dcmd と walker の名前解決」に説明されている名前解決規則に従って、モジュールの名前空間、およびデバッガの大域名前空間に追加されます。この関数は成功した場合 0 を返しますが、指定された walker 名がすでにこのモジュールによって登録済みであったり、walker の構造体 w が正しく構築されていなかったりした場合、エラーとして -1 を返します。mdb_walker_t w の情報が内部のデバッガ構造体にコピーされるため、呼び出し元では mdb_add_walker() を呼び出したあとにこの構造体を再使用または解放できます。

mdb_remove_walker()

int mdb_remove_walker(const char *name);

指定された name の walker を削除します。この関数は成功すると 0 を返し、エラーが発生すると -1 を返します。walker は現在のモジュールの名前空間から削除されます。walker 名が認識されない場合や、別のモジュールの名前空間だけに登録されている場合、この関数は失敗します。mdb_remove_walker() 関数を使用すると、mdb_add_walker() を使用して動的に追加された walker、またはモジュールのリンク構造の一部として静的に追加された walker を削除することができます。walker 名の有効範囲を指定する演算子は、ここでは使用できません。mdb_remove_walker() の呼び出し元が、別のモジュールからエクスポートされた walker を削除しようとしても無効です。

mdb_vread() および mdb_vwrite()

ssize_t mdb_vread(void *buf, size_t nbytes, uintptr_t addr);
ssize_t mdb_vwrite(const void *buf, size_t nbytes, uintptr_t addr);

これらの関数は、addr パラメータで指定された、所定のターゲットの仮想アドレスからデータを読み取ったり、そのアドレスにデータを書き込んだりするのに使用します。mdb_vread() 関数は、成功した場合 nbytes を、エラーの場合 -1 を返します。指定されたアドレスからデータの一部しか読み取れなかったためにデータが切り捨てられた場合、-1 が返されます。mdb_vwrite() 関数は、成功した場合は実際に書き込まれたバイト数を返します。エラーが発生した場合は -1 を返します。

mdb_fread() および mdb_fwrite()

ssize_t mdb_fread(void *buf, size_t nbytes, uintptr_t addr);
ssize_t mdb_fwrite(const void *buf, size_t nbytes, uintptr_t addr);

これらの関数は、addr パラメータで指定されたターゲット仮想アドレスに対応するオブジェクトファイルの位置からデータを読み書きする機能を提供します。mdb_fread() 関数は、成功した場合 nbytes を、エラーの場合 -1 を返します。指定されたアドレスからデータの一部しか読み取れなかったためにデータが切り捨てられた場合、-1 が返されます。mdb_fwrite() 関数は、成功した場合は実際に書き込まれたバイト数を返します。エラーが発生した場合は -1 を返します。

mdb_pread() および mdb_pwrite()

ssize_t mdb_pread(void *buf, size_t nbytes, uint64_t addr);
ssize_t mdb_pwrite(const void *buf, size_t nbytes, uint64_t addr);

これらの関数は、addr パラメータで指定された、所定のターゲット物理アドレスからデータを読み取ったり、そのアドレスにデータを書き込んだりするのに使用します。mdb_pread() 関数は、成功した場合 nbytes を、エラーの場合 -1 を返します。指定されたアドレスからデータの一部しか読み取れなかったためにデータが切り捨てられた場合、-1 が返されます。mdb_pwrite() 関数は、成功した場合は実際に書き込まれたバイト数を返します。エラーが発生した場合は -1 を返します。

mdb_readstr()

ssize_t mdb_readstr(char *s, size_t nbytes, uintptr_t addr);

mdb_readstr() 関数は、ターゲットの仮想アドレス addr から始まる NULL で終了する C 文字列を、s で指定されたバッファーに読み込みます。バッファーのサイズは nbytes で指定されます。この文字列が長すぎてバッファーに収まらない場合、文字列はバッファーサイズで切り捨てられ、s[nbytes - 1] に NULL バイトが格納されます。成功した場合、末尾の NULL バイトを含めずに s に格納された文字列の長さが返され、失敗した場合はエラーを示す -1 が返されます。

mdb_writestr()

ssize_t mdb_writestr(const char *s, uintptr_t addr);

mdb_writestr() 関数は、NULL で終了する C 文字列を末尾の NULL バイトも含めて s から、ターゲットの仮想アドレス空間の addr で指定されたアドレスに書き込みます。成功した場合、末尾の NULL バイトを含めずに実際に書き込まれたバイト数が返され、失敗した場合はエラーを示す -1 が返されます。

mdb_readsym()

ssize_t mdb_readsym(void *buf, size_t nbytes, const char *name);

読み取りが開始される仮想アドレスが name で指定されたシンボルの値から取得される点以外は、mdb_readsym()mdb_vread() に似ています。その名前でシンボルが見つからなかった場合、または読み取りエラーが発生した場合は -1 が返されます。成功した場合は nbytes が返されます。

シンボルの検索の失敗と読み取りの失敗を区別する必要がある場合、呼び出し元ではまずシンボルを別に調べます。一次実行可能ファイルのシンボルテーブルを使用してシンボルが検索されます。シンボルが別のシンボルテーブルに存在する場合、最初に mdb_lookup_by_obj()、次に mdb_vread() の順で適用する必要があります。

mdb_writesym()

ssize_t mdb_writesym(const void *buf, size_t nbytes, const char *name);

mdb_writesym() は、書き込みが開始される仮想アドレスが name で指定されたシンボルの値から取得される点以外は、mdb_vwrite() と同じです。その名前でシンボルが見つからなかった場合は -1 が返されます。それ以外の場合、成功すると正常に書き込まれたバイト数が返され、エラーが発生すると -1 が返されます。一次実行可能ファイルのシンボルテーブルを使用してシンボルが検索されます。シンボルが別のシンボルテーブルに存在する場合、最初に mdb_lookup_by_obj()、次に mdb_vwrite() の順で適用する必要があります。

mdb_readvar() および mdb_writevar()

ssize_t mdb_readvar(void *buf, const char *name);
ssize_t mdb_writevar(const void *buf, const char *name);

読み取りが開始される仮想アドレスと読み取るバイト数が name で指定されたシンボルの値とサイズから取得される点以外は、mdb_readvar()mdb_vread() に似ています。その名前でシンボルが見つからなかった場合は -1 が返されます。成功するとシンボルのサイズ、すなわち正常に読み取られたバイト数が返され、エラーが発生すると -1 が返されます。この関数はサイズの固定している既知の変数を読み取る場合に有用です。次にその例を示します。

				int hz; 	/* システムクロックレート */
				mdb_readvar(&hz, "hz");

シンボルの検索の失敗と読み取りの失敗を区別する必要がある場合、呼び出し元ではまずシンボルを別に調べます。また、局所宣言がターゲットの定義とまったく同じであることを確認するために、呼び出し元では当該のシンボルの定義を注意して調べる必要があります。たとえば、呼び出し元が int を宣言しているのに当該のシンボルが実際には long であったため、デバッガが 64 ビットのカーネルターゲットを調べている場合、mdb_readvar() は 8 バイトを呼び出し元のバッファーに戻すため、int に格納される分のあとに残る 4 バイトが破壊されてしまいます。

書き込みが開始される仮想アドレスと書き込むバイト数が name で指定されたシンボルの値とサイズから取得される点以外は、mdb_writevar()mdb_vwrite() と同じです。その名前でシンボルが見つからなかった場合は -1 が返されます。それ以外の場合、成功すると正常に書き込まれたバイト数が返され、エラーが発生すると -1 が返されます。

どちらの関数も、シンボルの検索では一次実行可能ファイルのシンボルテーブルが使用されます。シンボルが別のシンボルテーブルに存在する場合、最初に mdb_lookup_by_obj()、次に mdb_vread() または mdb_vwrite() の順で適用する必要があります。

mdb_lookup_by_name() および mdb_lookup_by_obj()

int mdb_lookup_by_name(const char *name, GElf_Sym *sym);
int mdb_lookup_by_obj(const char *object, const char *name, GElf_Sym *sym);

指定されたシンボル名を検索し、ELF シンボル情報を sym の指す GElf_Sym にコピーします。シンボルが見つかった場合、この関数は 0 を返します。それ以外の場合は -1 を返します。name パラメータはシンボル名を指定します。object パラメータは、デバッガにシンボルを検索する場所を指示します。mdb_lookup_by_name() 関数では、オブジェクトファイルは MDB_OBJ_EXEC にデフォルト設定されます。mdb_lookup_by_obj() では、オブジェクト名は次のどれかになります。

MDB_OBJ_EXEC

実行可能ファイルのシンボルテーブル (.symtab セクション) を検索します。カーネルクラッシュダンプの場合、このテーブルは unix.X ファイルまたは /dev/ksyms のシンボルテーブルに相当します。

MDB_OBJ_RTLD

実行時リンカーのシンボルテーブルを検索します。カーネルクラッシュダンプの場合、このテーブルは krtld モジュールのシンボルテーブルに相当します。

MDB_OBJ_EVERY

すべての既知のシンボルテーブルを検索します。カーネルクラッシュダンプの場合、この中には unix.X ファイルまたは /dev/ksyms.symtab および .dynsym セクションのほか、モジュール単位のシンボルテーブルが処理されていればそれらのテーブルも含まれます。

object

特定のロードオブジェクト名が明示的に指定されている場合、検索はこのオブジェクトのシンボルテーブルだけに限定されます。オブジェクトは、「シンボルの名前解決」に説明されているロードオブジェクトのための命名規則に従って命名されます。

mdb_lookup_by_addr()

int mdb_lookup_by_addr(uintptr_t addr, uint_t flag, char *buf,
				size_t len, GElf_Sym *sym);

指定されたアドレスに対応するシンボルを検索し、ELF シンボル情報を sym の指す GElf_Sym に、シンボル名を buf で指定された文字配列にコピーします。対応するシンボルが見つかった場合、この関数は 0 を返します。見つからない場合は -1 を返します。

flag パラメータは検索モードを指定するもので、次のどれかになります。

MDB_SYM_FUZZY

現在のシンボルディスタンスの設定に基づいて、あいまい一致検索を実行できます。シンボルディスタンスは、::set -s 組み込みコマンドを使用して制御することができます。シンボルディスタンスが明示的に設定されている場合、すなわち絶対モードの場合、シンボルの値からアドレスまでの距離が絶対シンボルディスタンスを超えなければ、アドレスはシンボルと一致します。スマートモードが有効な場合、すなわちシンボルディスタンス = 0 の場合、アドレスが有効範囲内、すなわちシンボルの値からシンボルの値 + シンボルのサイズまでの範囲であればシンボルと一致します。

MDB_SYM_EXACT

あいまい一致検索を許可しません。シンボル値が指定されたアドレスと厳密に等しい場合だけ、シンボルはアドレスと一致します。

シンボルが一致すると、シンボル名が呼び出し元の提供した buf にコピーされます。len パラメータはこのバッファーの長さをバイト単位で指定します。呼び出し元の buf は、少なくとも MDB_SYM_NAMLEN バイト必要です。デバッガはシンボル名をこのバッファーにコピーし、後ろに NULL の 1 バイトを追加します。名前の長さがバッファーの長さを超えると、シンボル名は切り捨てられますが、末尾には常に NULL の 1 バイトが存在します。

mdb_getopts()

int mdb_getopts(int argc, const mdb_arg_t *argv, ...);

指定された引数の配列 (argv) からオプションとオプションの引数を構文解析し、処理します。argc パラメータは引数配列の長さを示します。この関数は各引数を順に処理し、処理できない引数があると停止して、その配列の索引を返します。すべての引数が正常に処理できた場合、argc を返します。

argc および argv パラメータの後ろに、mdb_getopts() 関数では、argv 配列に入る予定のオプションを記述した可変の引数リストを指定できます。各オプションはオプション文字 (char 引数)、オプションタイプ (uint_t 引数)、および次の表に示すような 1 つまたは 2 つのその他の引数で記述されます。オプション引数のリストの末尾は NULL 引数となっています。タイプは次のどれかです。

MDB_OPT_SETBITS

指定されたビットとフラグワードとの論理和をとります。このオプションは次のパラメータで記述されます。

char c, uint_t type, uint_t bits, uint_t *p

タイプが MDB_OPT_SETBITS であり、argv リストでオプション c が検出された場合、デバッガはポインタ p の参照する整数と指定ビットの論理和をとります。

MDB_OPT_CLRBITS

指定されたビットをフラグワードから消去します。このオプションは次のパラメータで記述されます。

char c, uint_t type, uint_t bits, uint_t *p

タイプが MDB_OPT_CLRBITS であり、argv リストでオプション c が検出された場合、デバッガはポインタ p の参照する整数から指定ビットを消去します。

MDB_OPT_STR

文字列引数をとります。このオプションは次のパラメータで記述されます。

char c, uint_t type, const char **p

タイプが MDB_OPT_STR であり、argv リストでオプション c が検出された場合、デバッガは c の後ろに続く文字列引数を指すポインタを p の参照しているポインタに格納します。

MDB_OPT_UINTPTR

uintptr_t 引数をとります。このオプションは次のパラメータで記述されます。

char c, uint_t type, uintptr_t *p

タイプが MDB_OPT_UINTPTR であり、argv リストでオプション c が検出された場合、デバッガは c の後ろに続く整数引数を p の参照している uintptr_t に格納します。

MDB_OPT_UINTPTR_SET

uintptr_t 引数をとります。このオプションは次のパラメータで記述されます。

char c, uint_t type, boolean_t *flag, uintptr_t *p

タイプが MDB_OPT_UINTPTR_SET であり、argv リストでオプション c が検出された場合、デバッガは flag の参照している boolean_t に値 1 (TRUE) を格納し、c の後ろに続く整数引数を p の参照している uintptr_t に格納します。

MDB_OPT_UINT64

uint64_t 引数をとります。このオプションは次のパラメータで記述されます。

char c, uint_t type, uint64_t *p

タイプが MDB_OPT_UINT64 であり、argv リストでオプション c が検出された場合、デバッガは c の後ろに続く整数引数を p の参照している uint64_t に格納します。

たとえば、次のソースコードの場合を考えます。

int
dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
        uint_t opt_v = FALSE;
        const char *opt_s = NULL;

        if (mdb_getopts(argc, argv,
            'v', MDB_OPT_SETBITS, TRUE, &opt_v,
            's', MDB_OPT_STR, &opt_s, NULL) != argc)
                return (DCMD_USAGE);

        /* ... */
}

このコードは、mdb_getopts() を dcmd で使用して、ブール型のオプション「-v」(opt_v 変数を TRUE に設定する) と「-s」(opt_s 変数に格納された文字列引数を受け入れる) を受け入れる方法を示しています。mdb_getopts() 関数は、呼び出し元に戻る前に無効なオプション文字やオプション引数の欠落を検出すると、自動的に警告メッセージを表示します。引数文字列および argv 配列のための記憶領域は、dcmd が完了するとデバッガにより自動的にガベージコレクションに集められます。

mdb_strtoull()

u_longlong_t mdb_strtoull(const char *s);

指定された文字列 s符号なし long long 表現に変換します。この関数は、mdb_getopts() が適当でない状況において文字列引数を処理し変換します。文字列引数が有効な整数表現に変換できない場合、関数は失敗し、該当するエラーメッセージが出力され、dcmd は異常終了します。したがって、エラーチェックコードは不要です。文字列には、先頭に有効な基底指示子 (0i、0I、0o、0O、0t、0T、0x、または 0X) を付けることができますが、付けない場合はデフォルトの基底を使用するものと解釈されます。s の中に基底文字として適切でない文字があったり、整数のオーバーフローが発生したりすると、この関数は失敗し、dcmd は異常終了します。

mdb_alloc()mdb_zalloc() および mdb_free()

void *mdb_alloc(size_t size, uint_t flags);
void *mdb_zalloc(size_t size, uint_t flags);
void mdb_free(void *buf, size_t size);

mdb_alloc()size バイトのデバッガメモリーを割り当て、割り当てたメモリーを指すポインタを返します。割り当て済みメモリーは、どのような C 構造体でも保持できるように、少なくともダブルワードが割り当てられます。それ以上の割り当てはできません。flags パラメータは、次の 1 つ以上の値のビット単位の論理和となります。

UM_NOSLEEP

要求を満たすだけの十分なメモリーがすぐに使用可能でない場合、失敗を示す NULL が返されます。呼び出し元は NULL が返されたかどうかをチェックして、NULL の場合には適切に対処する必要があります。

UM_SLEEP

要求を満たすだけの十分なメモリーがすぐに使用可能でない場合、要求を満たすことができるまでの間、スリープ (休眠) します。したがって、UM_SLEEP 割り当ての場合、成功することが保証されています。呼び出し元で NULL 戻り値をチェックする必要はありません。

UM_GC

このデバッガコマンドの終わりに自動的に割り当てのガベージコレクションを行います。割り当ての解除はデバッガによって自動的に行われるので、呼び出し元はこのブロックにおいてそれ以降 mdb_free() を呼び出すことはできません。dcmd がユーザーによって中断された場合、デバッガが不要メモリーのガベージコレクションを実行できるように、dcmd の中からメモリーの割り当てを行うときは、必ず UM_GC を使用する必要があります。

mdb_zalloc()mdb_alloc() と似ていますが、呼び出し元に戻る前に割り当てたメモリーにはゼロが入ります。mdb_alloc() から戻されるメモリーの初期内容は、保証されません。mdb_free() は、UM_GC で割り当てられたメモリー以外の、以前に割り当て済みのメモリーを解放するのに使用します。バッファーアドレスとサイズは元の割り当てと正確に一致している必要があります。mdb_free() を使用して割り当ての一部だけを解放することはできません。また、二度以上割り当てを解放することもできません。ゼロバイトの割り当てでは、常に NULL が返されます。サイズがゼロの NULL ポインタの解放は、常に成功します。

mdb_printf()

void mdb_printf(const char *format, ...);

指定された書式文字列と引数を使用して、書式付き出力を書き出します。警告とエラーメッセージを除いて、モジュール作成者はあらゆる出力に対して mdb_printf() を使用する必要があります。この関数は必要に応じて自動的に組み込み出力ページャーをトリガーします。mdb_printf() 関数は printf(3C) に似ていますが、次のような例外があります。ワイド文字列に対して %C%S、および %ws 指示子はサポートされていない、%f 浮動小数点形式がサポートされていない、代替ダブルフォーマットに対する %e%E%g、および %G 指示子では、単一形式の出力だけが生成される、書式 %.n の精度の指定はサポートされていない、という点です。サポートされている指示子のリストを次に示します。

フラグ指示子

%#

書式文字列の中に # 記号があった場合、与えられたフォーマットの代替書式を選択します。すべてのフォーマットに代替書式があるとは限りません。代替書式はフォーマットによって異なります。代替書式の詳細については、以降のフォーマットの説明を参照してください。

%+

符号付きの値を出力する場合、常に符号として「+」または「-」の接頭辞を表示します。%+ を指定しない場合、正の値には符号の接頭辞が付かず、負の値には先頭に「-」の接頭辞が付けられます。

%-

指定されたフィールド幅の中で出力を左詰めにします。出力の幅が指定されたフィールド幅より小さい場合、右側には空白文字が入ります。%- を指定しない場合、デフォルトの設定では値は右詰めになります。

%0

出力が右詰めで出力幅が指定されたフィールドの幅より小さい場合、出力フィールドがゼロで埋められます。%0 を指定しない場合、右詰めにした値の前の残りのフィールドには空白文字が入ります。

フィールド幅の指示子

%n

フィールド幅は指定された 10 進数値に設定されます。

%?

フィールド幅は 16 進数のポインタ値の最大幅に設定されます。この値は ILP32 環境では 8、LP64 環境では 16 です。

%*

フィールド幅は引数リストの現在の位置で指定された値に設定されます。この値は int であるとみなされます。64 ビットのコンパイル環境では、long 値を int にキャストしなければならない場合があります。

整数指示子

%h

short 型の整数値が出力されます。

%l

long 型の整数値が出力されます。

%ll

long long 型の整数値が出力されます。

端末属性指示子

デバッガの標準出力が端末であり、terminfo データベースから端末属性を変更できる場合、次の端末エスケープコンストラクトが使用できます。

%<n>

n に対応する端末属性を有効にします。%<> のインスタンスごとに、1 つの属性だけを有効にできます。

%</n>

n に対応する端末属性を無効にします。反転表示、選択不可テキスト、およびボールドテキストの場合、これらの属性を無効にする端末コードは同じである可能性があります。したがって、これらの属性を互いに独立して無効にはできない場合があります。

端末情報が使用できない場合、各端末属性コンストラクトは mdb_printf() で無視されます。端末属性については、terminfo(4) のマニュアルページを参照してください。使用可能な terminfo 属性は次のとおりです。

a

代替文字セット

b

ボールドテキスト

d

選択不可テキスト

r

反転表示

s

強調表示機能

u

下線

書式指示子

%%

%」記号が出力されます。

%a

アドレスが記号形式で出力されます。%a に関連付けられている値の最小サイズは uintptr_t です。%la を指定する必要はありません。アドレスからシンボルへの変換が有効な場合、デバッガはアドレスを現在の出力の基数でのシンボル名とそれに続くオフセットに変換して、この文字列を出力しようとします。変換が有効でない場合、アドレス値はデフォルトの出力の基数で出力されます。%#a を使用した場合、代替書式によって出力に「:」接尾辞が付加されます。

%A

この書式は %a と同じですが、アドレスがシンボル名とオフセットに変換できない場合は何も出力されない点が異なっています。%#A を使用した場合、アドレス変換が失敗したとき、代替書式によって「?」が出力されます。

%b

ビットフィールドを記号書式で復号化し、出力します。この指示子は 2 つの連続する引数をとります。この 2 つの引数はビットフィールド値 (%b に対する int%lb に対する long など) および mdb_bitmask_t 構造体の配列を指すポインタです。

typedef struct mdb_bitmask {
		const char *bm_name;       /* 出力する文字列 */
		u_longlong_t bm_mask;      /* ビット用マスク */
		u_longlong_t bm_bits;      /* 値とマスクの結果 */
} mdb_bitmask_t;

配列の末尾は bm_name フィールドが NULL に設定されている構造体でなければなりません。%b を使用した場合、デバッガは値の引数を読み取り、各 mdb_bitmask 構造体を繰り返して、次の条件をチェックします。

(value & bitmask->bm_mask) == bitmask->bm_bits

この式が真の場合、bm_name 文字列が出力されます。各文字列はコンマで区切って出力されます。次の例は、%b を使用して kthread_tt_flag フィールドを復号化する方法を示しています。

const mdb_bitmask_t t_flag_bits[] = {
		{ "T_INTR_THREAD", T_INTR_THREAD, T_INTR_THREAD },
		{ "T_WAKEABLE", T_WAKEABLE, T_WAKEABLE },
		{ "T_TOMASK", T_TOMASK, T_TOMASK },
		{ "T_TALLOCSTK", T_TALLOCSTK, T_TALLOCSTK },
			...
		{ NULL, 0, 0 }
};

void
thr_dump(kthread_t *t)
{
		mdb_printf("t_flag = <%hb>\n", t->t_flag, t_flag_bits);

		...
}

t_flag が 0x000a に設定されている場合、この関数によって次のように出力されます。

t_flag = <T_WAKEABLE,T_TALLOCSTK>

%#b を指定した場合、復号化された名前の後ろに、ビットマスク配列内の要素と一致しなかったすべてのビットが 16 進数値として出力されます。

%c

指定された整数を ASCII 文字として出力します。

%d

指定された整数を符号付き 10 進数値として出力します。%i と同じです。%#d を指定すると、代替書式によって値の先頭に「0t」が付けられます。

%e

指定された倍精度数を浮動小数点形式 [+/-]d.ddddddde[+/-]dd で出力します。小数点の前が 1 桁、小数点以下が 7 桁で、指数の後は少なくとも 2 桁です。

%E

指定された倍精度数を %e と同じ規則を使用して出力しますが、指数文字として「e」ではなく「E」を使用する点が異なっています。

%g

指定された倍精度数を %e と同じ浮動小数点形式で出力しますが、16 桁を使用します。%llg を指定した場合、引数の型は 4 倍精度浮動小数点数の long double となります。

%G

指定された倍精度数を %g と同じ規則を使用して出力しますが、指数文字として「e」ではなく「E」を使用する点が異なっています。

%i

指定された整数を符号付き 10 進数値として出力します。%d と同じです。%#i を指定すると、代替書式によって値の先頭に「0t」が付けられます。

%I

指定された 32 ビット符号なし整数をドット付き 10 進形式のインターネット IPv4 アドレスとして出力します。たとえば、16 進数値の 0xffffffff255.255.255.255 として出力されます。

%m

空白のマージンを印刷します。フィールドを指定しないと、デフォルトの出力マージン幅が使用されます。フィールド幅を指定すると、フィールド幅によって出力される空白の文字数が決定されます。

%o

指定された整数を符号なし 8 進数値として出力します。%#o を使用した場合、代替書式によって出力の先頭に「0」が付けられます。

%p

指定されたポインタ (void *) を 16 進数値として出力します。

%q

指定された整数を符号付き 8 進数値として出力します。%#o を使用した場合、代替書式によって出力の先頭に「0」が付けられます。

%r

指定された整数を現在の出力の基数での符号なし値として出力します。ユーザーは $d dcmd を使用して出力の基数を変更することができます。%#r を指定すると、代替書式によって値の先頭に該当する基底接頭辞が付けられます。2 進数の場合「0i」、8 進数の場合「0o」、10 進数の場合「0t」、16 進数の場合「0x」です。

%R

指定された整数を現在の出力の基数で符号付きの値として出力します。%#R を指定すると、代替書式によって値の先頭に該当する基底接頭辞が付けられます。

%s

指定された文字列 (char *) を出力します。文字列のポインタが NULL の場合、文字列「<NULL>」が出力されます。

%t

1 つまたは複数のタブストップまで進みます。幅を指定しないと、次のタブストップまで出力します。幅を指定すると、フィールド幅によって進むタブストップの数が決定されます。

%T

カラムをフィールド幅の倍数分出力します。フィールド幅を指定しないと、何の処理も実行されません。現在出力されているカラムがフィールド幅の倍数でない場合、空白が付加されてカラムが出力されます。

%u

指定された整数を符号なし 10 進数値として出力します。%#u を指定すると、代替書式によって値の先頭に「0t」が付けられます。

%x

指定された整数を 16 進数値として出力します。10 から 15 までの値を表す数字として、a から f までの文字を使用します。%#x を指定すると、代替書式によって値の先頭に「0x」が付けられます。

%X

指定された整数を 16 進数値として出力します。10 から 15 までの値を表す数字として、A から F までの文字を使用します。%#X を指定すると、代替書式によって値の先頭に「0X」が付けられます。

%Y

指定された time_t を文字列「year month day HH:MM:SS」として出力します。

mdb_snprintf()

size_t mdb_snprintf(char *buf, size_t len, const char *format, ...);

指定された書式文字列と引数に基づいて書式付き文字列を作成し、作成した文字列を指定された buf に格納します。mdb_snprintf() 関数は mdb_printf() 関数と同じ書式指示子と引数をとります。len パラメータは buf のサイズをバイト単位で指定します。フォーマットされた len - 1 バイト以下のバイトが buf に格納されます。mdb_snprintf() では、常に buf の末尾は NULL の 1 バイトで終了します。この関数は、末尾の NULL のバイトを除外した、完全な書式付き文字列に必要なバイト数を返します。buf パラメータが NULL で len がゼロに設定されている場合、buf には何も格納されず、完全な書式付き文字列に必要なバイト数が返されます。この方法を使用して、動的メモリー割り当て用のバッファーの適切なサイズが決定されます。

mdb_warn()

void mdb_warn(const char *format, ...);

エラーまたは警告メッセージを標準エラーに出力します。mdb_warn() 関数では、書式文字列と mdb_printf() で掲げられているすべての指示子を含む可変の引数リストを指定することができます。ただし、mdb_warn() の出力が標準エラーに送られる場合は、バッファーには格納されず、出力ページャーを通して送信されたり、dcmd パイプラインの一部として処理されることはありません。すべてのエラーメッセージの先頭には自動的に、「mdb:」という接頭辞が付けられます。

さらに、format パラメータに復帰改行 (\n) 文字が含まれていない場合は、書式文字列の末尾には暗黙的に文字列「: %s\n」が付けられます。ここで、%s はモジュール API 関数が最後に記録したエラーに対応するエラーメッセージ文字列に置換されます。たとえば、次のソースコードの場合を考えます。

if (mdb_lookup_by_name("no_such_symbol", &sym) == -1)
       mdb_warn("lookup_by_name failed");

この場合、次のような出力が得られます。

mdb: lookup_by_name failed: unknown symbol name

mdb_flush()

void mdb_flush(void);

現在バッファー化されているすべての出力をフラッシュします。通常、mdb の標準出力はラインバッファーに格納されます。mdb_printf() で生成された出力は、復帰改行文字を見つけるまで、あるいは現在の dcmd の終わりまで、端末またはほかの標準出力の出力先にフラッシュされません。しかし、状況によっては、復帰改行文字を出力する前に標準出力を明示的にフラッシュする必要がある場合もあります。そのような場合に、この mdb_flush() 関数が使用できます。

mdb_nhconvert()

void mdb_nhconvert(void *dst, const void *src, size_t nbytes);

src で指定されたアドレスに格納されている nbytes バイトのシーケンスをネットワークバイト順からホストバイト順に変換して、その結果を dst で指定されたアドレスに格納します。src パラメータと dst パラメータが同じ場合、オブジェクトはそのアドレスのままで変換されます。変換は同じように行われるので、この関数はホスト順からネットワーク順に変換する場合にも、ネットワーク順からホスト順に変換する場合にも使用できます。

mdb_dumpptr() および mdb_dump64()

int mdb_dumpptr(uintptr_t addr, size_t nbytes, uint_t flags,
                     mdb_dumpptr_cb_t func, void *data);
int mdb_dump64(uint64_t addr, uint64_t nbytes, uint_t flags,
                     mdb_dump64_cb_t func, void *data);

これらの関数を使用すると、書式化された 16 進数および ASCII のデータダンプを生成して標準出力に出力できます。どらちの関数も、開始場所を指定する addr パラメータ、表示するバイト数を指定する nbytes パラメータ、フラグセット (次を参照)、表示するデータを読み取るために使用する func コールバック関数、そして、func コールバック関数の呼び出しごとに最後の引数として渡されるデータパラメータを受け入れます。これらの関数はほとんど同じですが、mdb_dumpptruintptr_t をアドレスパラメータとして使用し、mdb_dump64uint64_t を使用します。この区別は、たとえば、mdb_dump64mdb_pread に結びつけるときに便利です。組み込み ::dump dcmd はこれらの関数を使用してデータを表示します。

flags パラメータは、次の 1 つ以上の値のビット単位の論理和となります。

MDB_DUMP_RELATIVE

各行に、絶対的なアドレスではなく、開始アドレスからの相対的な行数を与えます。

MDB_DUMP_ALIGN

出力を段落境界に揃えます。

MDB_DUMP_PEDANT

アドレスを 80 カラムに揃えて切り捨てるのではなく、完全な幅で表示します。

MDB_DUMP_ASCII

16 進数データの次に ASCII 値を表示します。

MDB_DUMP_HEADER

データについてのヘッダー行を表示します。

MDB_DUMP_TRIM

行全体を読み取って出力するのではなく、指定されたアドレスの内容だけを読み取って表示します。

MDB_DUMP_SQUISH

前の行を繰り返している行に「*」を表示することによって、繰り返し行を省略します。

MDB_DUMP_NEWDOT

ドット値を、関数が読み取った最後のアドレスを超えるアドレスに更新します。

MDB_DUMP_ENDIAN

エンディアン性を調整します。このオプションは、ワードサイズが (MDB_DUMP_GROUP() で指定される) 現在のグループサイズと同じであることを想定します。このオプションは常に、整列、ヘッダー、および ASCII 表示をオフにして、出力が乱れることを防ぎます。MDB_DUMP_TRIM MDB_DUMP_ENDIAN が一緒に設定されている場合、ダンプされるバイト数はもっとも近いワードサイズのバイトに切り捨てられます。

MDB_DUMP_WIDTH(width )

表示される行ごとに 16 バイト段落の数をインクリメントします。width のデフォルト値は 1 で、最大値は 16 です。

MDB_DUMP_GROUP(group )

バイトグループのサイズを group に設定します。デフォルトの group サイズは 4 バイトです。group サイズは行幅を分割する 2 のべき乗にする必要があります。

mdb_one_bit()

const char *mdb_one_bit(int width, int bit, int on);

mdb_one_bit() 関数を使用して、関連のある 1 つのビットをオンまたはオフにして、ビットフィールドを図式化して出力することができます。この関数は snoop(1M) -v を使用して出力する場合と同様に、ビットフィールドを詳細に表示するのに有用です。たとえば、次のソースコードの場合を考えます。

#define FLAG_BUSY       0x1

uint_t flags;

/* ... */

mdb_printf("%s = BUSY\n", mdb_one_bit(8, 0, flags & FLAG_BUSY));

この場合、次のような出力が得られます。

.... ...1 = BUSY

4 ビットごとに空白で区切られ、ビットフィールドの各ビットがピリオド (. ) として出力されます。on パラメータの設定に従って、関連のあるビットは 1 または 0 で出力されます。ビットフィールドの合計の幅は width パラメータによりビット単位で指定し、関連のあるビットの位置は bit パラメータで指定します。ビットにはゼロから番号が付けられます。この関数はフォーマットされたビット表現を含む、適切なサイズの、NULL で終了する文字列を返します。現在の dcmd が完了すると、不要な文字列は自動的に回収されます。

mdb_inval_bits()

const char *mdb_inval_bits(int width, int start, int stop);

mdb_inval_bits() 関数は mdb_one_bit() とともに使用して、ビットフィールドを図式化して出力します。この関数は、該当するビット位置に「x」を表示することによって、そのビットを無効または予約済みとしてマーク付けします。ビットフィールドの各ビットはピリオド (.) で表現されますが、start および stop パラメータで指定された範囲のビット位置にあるビットは対象外です。ビットにはゼロから番号が付けられます。たとえば、次のソースコードの場合を考えます。

mdb_printf("%s = reserved\n", mdb_inval_bits(8, 7, 7));

この場合、次のような出力が得られます。

x... .... = reserved

この関数はフォーマットされたビット表現を含む、適切なサイズの、NULL で終了する文字列を返します。現在の dcmd が完了すると、不要な文字列は自動的に回収されます。

mdb_inc_indent() および mdb_dec_indent ()

ulong_t mdb_inc_indent(ulong_t n);
ulong_t mdb_dec_indent(ulong_t n);

これらの関数は、1 行出力する前に MDB によって空白で自動インデントされるカラム数を増減させます。デルタのサイズはカラム数、n で指定します。どちらの関数も前の絶対インデント値を返します。ゼロより小さい値にインデントを設定しようとしても無効です。どちらかの関数を呼び出したあとに、mdb_printf() を呼び出すと、適切にインデントされています。dcmd が完了するか、ユーザーによって強制終了された場合、デバッガによってインデントは自動的にデフォルトの設定に戻ります。

mdb_eval()

int mdb_eval(const char *s);

指定されたコマンド文字列 s を、デバッガによって標準入力から読み取られたものとして、評価し実行します。この関数は成功すると 0 を返し、エラーが発生すると -1 を返します。コマンド文字列に構文エラーがあったり、mdb_eval() によって実行されたコマンド文字列がユーザーからのページャーまたは割り込みの発生によって強制終了されたりすると、この関数は失敗します。

mdb_set_dot() および mdb_get_dot()

void mdb_set_dot(uintmax_t dot);
uintmax_t mdb_get_dot(void);

ドット (「.」変数) の現在の値を設定するか、または取得します。モジュールを開発する上でドットの位置を再設定する必要があるのは、たとえば dcmd が前回読み取ったアドレスに続くアドレスを参照する場合などです。

mdb_get_pipe()

void mdb_get_pipe(mdb_pipe_t *p);

現在の dcmd に対するパイプライン入力バッファーの内容を取り出します。mdb_get_pipe() 関数は、dcmd で実行されますがパイプ入力要素ごとにデバッガから繰り返し呼び出されるのではなく、パイプ入力された要素全体を一度に呼び出して、一度だけ実行されます。mdb_get_pipe()がいったん呼び出されると、その dcmd は現在のコマンドの一部として再び起動されることはありません。これは、たとえば入力値のセットをソートする dcmd を作成するときに使用できます。

不要になったパイプの内容は、dcmd が完了すると配列の中に回収されます。この配列のポインタは p->pipe_data に格納されます。配列の長さは p->pipe_len に格納されます。dcmd がパイプラインの右側で実行されなかった場合、すなわち、flags パラメータに DCMD_PIPE フラグが設定されなかった場合、p->pipe_data は NULL に設定され、p->pipe_len はゼロに設定されます。

mdb_set_pipe()

void mdb_set_pipe(const mdb_pipe_t *p);

パイプラインの出力バッファーをパイプ構造体 p によって記述された内容に設定します。パイプの値は配列 p->pipe_data に置かれ、配列の長さは p->pipe_len に格納されます。デバッガはこの情報の独自のコピーを作成するため、呼び出し元で必要に応じて p->pipe_data を解放する必要があります。パイプライン出力バッファーが以前に空でなかった場合、その内容は新しい配列に格納されます。dcmd がパイプラインの左側で実行されなかった場合、すなわちフラグパラメータで DCMD_PIPE_OUT フラグが設定されなかった場合、この関数は無効です。

mdb_get_xdata()

ssize_t mdb_get_xdata(const char *name, void *buf, size_t nbytes);

name で指定されたターゲットの外部データバッファーの内容を、buf で指定されたバッファーの中に読み取ります。buf のサイズは nbytes パラメータで指定します。nbytes を超えるバイト数は呼び出し元のバッファーにコピーされません。成功すると読み取った合計バイト数が返され、エラーが発生すると -1 が返されます。呼び出し元は、指定した特定のバッファーのサイズを調べる場合には、buf を NULL に、nbytes をゼロに指定します。この場合、mdb_get_xdata() はバッファーの合計サイズをバイト単位で返しますが、データは読み取りません。外部データバッファーを使用することで、モジュールの作成者は、モジュール API を通してほかの方法ではアクセスできないターゲットデータにアクセスすることができます。現在のターゲットによってエクスポートされた指定されたバッファーのセットは、::xdata 組み込み dcmd を使用して参照できます。

その他の関数

さらに、モジュールの作成者は、次の string(3C) および bstring(3C) 関数も使用できます。これらの関数は、Solaris のマニュアルページに掲載されている関数と同じ意味を持っています。

strcat()           strcpy()                strncpy()
strchr()           strrchr()               strcmp()
strncmp()          strcasecmp()            strncasecmp()
strlen()           bcmp()                  bcopy()
bzero()            bsearch()               qsort()