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 中启用控制块 (enabling control block, 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),请将 4 字节的写入修饰符 (W) 与 / 格式设置 dcmd 一起使用:


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

继续使用 :c


kadb[0]: :c

要在继续之后重新启用破坏性操作,需要使用 mdb(1)dtrace_destructive_disallow 显式重置为 0:


# 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 显示指定的纳秒数。chill() 主要用于查找可能与计时相关的问题。例如,您可以使用此操作打开竞争情况窗口,或者使定期事件相互之间同步或异步。由于处于 DTrace 探测器上下文中时禁止中断,因此使用任何 chill() 都将引起中断延迟、调度延迟和分发延迟。因此,chill() 可能会导致意外的系统影响,不应毫无限制地使用。由于系统活动依赖于定期的中断处理,如果在任何给定 CPU 的每一秒间隔内,chill() 操作需要的时间超过 500 毫秒,DTrace 将拒绝执行。如果超过最大 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);}'