Solaris 動的トレースガイド

カーネル破壊アクション

システム全体に影響を及ぼす破壊アクションもあります。これらのアクションは、システム上のすべてのプロセスに影響を及ぼすだけでなく、影響を受けるシステムのネットワークサービスによっては、その他のシステムにも暗黙的または明示的に影響を及ぼします。したがって、これらのアクションを使用するときは、細心の注意を払ってください。

breakpoint()

void breakpoint(void)

breakpoint() アクションは、カーネルブレークポイントを設定して、システムを停止し、カーネルデバッガに制御を移します。カーネルデバッガは、アクションを引き起こした DTrace プローブを表す文字列を発行します。たとえば、次の内容を実行するとします。


# dtrace -w -n clock:entry'{breakpoint()}'
dtrace: allowing destructive actions
dtrace: description 'clock:entry' matched 1 probe

SPARC 版 Solaris 環境では、コンソールに次のメッセージが表示されます。


dtrace: breakpoint action at probe fbt:genunix:clock:entry (ecb 30002765700)
Type  'go' to resume
ok

x86 版 Solaris 環境では、コンソールに次のメッセージが表示されます。


dtrace: breakpoint action at probe fbt:genunix:clock:entry (ecb d2b97060)
stopped at      int20+0xb:      ret
kmdb[0]:

プローブ記述に続くアドレスは、DTrace 内の有効化制御ブロック (ECB) のアドレスです。このアドレスを使って、ブレークポイントアクションを引き起こすプローブ有効化の詳細情報を得ることができます。

breakpoint() アクションの操作を間違うと、このアクションが必要以上に何度も呼び出される可能性があります。この問題が発生すると、ブレークポイントアクションを引き起こす DTrace コンシューマを終了することもできなくなってしまう場合があります。そのような場合は、カーネル整数変数 dtrace_destructive_disallow を 1 に設定してください。この設定では、マシン上のすべての破壊アクションが拒否されます。この設定は、この特別な状況以外では適用しないでください。

dtrace_destructive_disallow の設定方法は、厳密には、使用しているカーネルデバッガによって異なります。SPARC システム上で OpenBoot PROM を使用している場合は、w! を使用します。


ok 1 dtrace_destructive_disallow w!
ok

w? を使って、変数が設定されたことを確認します。


ok dtrace_destructive_disallow w?
1
ok

go と入力して、処理を続行します。


ok go

x86 または SPARC システム上で kmdb(1) を使用している場合は、書式設定 dcmd であるスラッシュ (/) を入力し、続けて 4 バイトの書き込み修飾子 (W) を指定します。


kmdb[0]: dtrace_destructive_disallow/W 1
dtrace_destructive_disallow:    0x0             =       0x1
kmdb[0]:

:c と入力して、処理を続行します。


kadb[0]: :c

続行後、破壊アクションを再度有効にするには、mdb(1) を使って dtrace_destructive_disallow を明示的にゼロに戻す必要があります。


# echo "dtrace_destructive_disallow/W 0" | mdb -kw
dtrace_destructive_disallow:    0x1             =       0x0
#

panic()

void panic(void)

panic() アクションを引き起こすと、カーネルパニックが起こります。このアクションは、必要に応じて強制的にシステムのクラッシュダンプを実行するときに使用します。このアクションをリングバッファリングや事後分析と組み合わせることで、問題を把握できます。詳細は、第 11 章バッファーとバッファリング第 37 章事後トレースを参照してください。パニックアクションを使用すると、パニックの原因となったプローブを示すパニックメッセージが表示されます。次に例を示します。


  panic[cpu0]/thread=30001830b80: dtrace: panic action at probe
  syscall::mmap:entry (ecb 300000acfc8)

  000002a10050b840 dtrace:dtrace_probe+518 (fffe, 0, 1830f88, 1830f88,
    30002fb8040, 300000acfc8)
    %l0-3: 0000000000000000 00000300030e4d80 0000030003418000 00000300018c0800
    %l4-7: 000002a10050b980 0000000000000500 0000000000000000 0000000000000502
  000002a10050ba30 genunix:dtrace_systrace_syscall32+44 (0, 2000, 5,
    80000002, 3, 1898400)
    %l0-3: 00000300030de730 0000000002200008 00000000000000e0 000000000184d928
    %l4-7: 00000300030de000 0000000000000730 0000000000000073 0000000000000010

  syncing file systems... 2 done
  dumping to /dev/dsk/c0t0d0s1, offset 214827008, content: kernel
  100% done: 11837 pages dumped, compression ratio 4.66, dump
  succeeded
  rebooting...

syslogd(1M) も、リブート時にメッセージを発行します。


  Jun 10 16:56:31 machine1 savecore: [ID 570001 auth.error] reboot after panic:
  dtrace: panic action at probe syscall::mmap:entry (ecb 300000acfc8)

クラッシュダンプのメッセージバッファーには、プローブのほか、panic() アクションの原因となった ECB も含まれます。

chill()

void chill(int nanoseconds)

chill() アクションには、DTrace を指定された期間 (nanoseconds ナノ秒間) 待つ働きがあります。chill() は、主にタイミング関連の問題の調査に使用します。たとえば、このアクションを使って、競合しているウィンドウを開いたり、定期イベントを同期させたり、定期イベントの同期を解除したりできます。DTrace プローブコンテキストでは、割り込みは無効になります。このため、chill() を使用すると、割り込み遅延、スケジュール遅延、およびディスパッチ遅延が発生します。このように、chill() は、システム全体に思いがけない影響を及ぼすことがあるので、乱用は避けてください。システムアクティビティは定期的な割り込み処理に依存します。このため、DTrace は、CPU 上で 1 秒間隔のうち 500 ミリ秒間を超えて chill() アクションを実行することを拒否します。最大 chill() 間隔を超過すると、DTrace は、次の例のように、不正な操作を表すエラーを返します。


# dtrace -w -n syscall::open:entry'{chill(500000001)}'
dtrace: allowing destructive actions
dtrace: description 'syscall::open:entry' matched 1 probe
dtrace: 57 errors
CPU     ID                    FUNCTION:NAME
dtrace: error on enabled probe ID 1 (ID 14: syscall::open:entry): \
  illegal operation in action #1

chill() への複数の呼び出しによる合計、または単一のプローブを使用する複数の DTrace コンシューマによる合計が、この時間制限を超えた場合も同様です。たとえば、次のコマンドでも、同じエラーが生成されます。


# dtrace -w -n syscall::open:entry'{chill(250000000); chill(250000001);}'