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 はフラグパラメタに 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 はフラグパラメタに 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_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_UINT64

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

char c, uint_t type, uint64_t *p

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

たとえば、次のソースコードは、dcmd で mdb_getopts() を使用して、opt_v 変数を TRUE に設定するブール型オプション "-v"、および opt_s 変数に格納されている文字列引数をとるオプション "-s" をとる方法を示しています。

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() 関数は、呼び出し元に戻る前に無効なオプション文字やオプション引数の欠落を検出すると、自動的に警告メッセージを表示します。引数文字列および 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>

%c

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

%d

指定された整数を符号付き 10 進数値として出力します。%i と同じです。

%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

指定された 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 進数値として出力します。

%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_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 がパイプラインの右側で実行されなかった場合、すなわちフラグパラメタで 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()