Solaris 动态跟踪指南

指针安全

如果您是 C 或 C++ 语言程序员,在阅读上节内容后可能会有些担心,因为您知道在程序中错误地使用指针会导致程序崩溃。DTrace 是一个强大、安全的环境,在其中执行 D 程序时,错误地使用指针不会导致程序崩溃。即使您确实编写了有很多错误的 D 程序,无效的 D 指针访问也绝对不会导致 DTrace 或操作系统内核故障或崩溃。相反,DTrace 软件会检测所有无效的指针访问,禁用检测过程并报告问题以便进行调试。

如果您使用过 Java 编程语言进行编程,则您可能知道,基于同样的安全原因,Java 语言不支持指针。因为指针在 C 语言中是操作系统实现的固有部分,所以它们在 D 中是必需的,但 DTrace 实现了与 Java 编程语言中相同的安全机制,可以避免包含错误的程序破坏自身或彼此破坏。DTrace 的错误报告类似于 Java 编程语言的运行时环境,它可以检测编程错误并向您报告异常。

要了解 DTrace 的错误处理和报告,请编写使用指针并且有意出错的 D 程序。在编辑器中,键入以下 D 程序并将其保存在名为 badptr.d 的文件中:


示例 5–1 badptr.d:DTrace 错误处理的演示

BEGIN
{
	x = (int *)NULL;
	y = *x;
	trace(y);
}

badptr.d 程序将创建名为 x 的 D 指针,它是指向 int 的指针。程序将特殊的无效指针值 NULL 赋给此指针,该值是地址 0 的内置别名。根据约定,地址 0 始终定义为无效,所以 NULL 可用作 C 程序和 D 程序中的标记值。程序使用强制转换表达式将 NULL 转换为指向整数的指针。然后程序使用表达式 *x 取消引用指针,并且将结果赋给另一个变量 y,然后尝试跟踪 y。在执行 D 程序时,DTrace 会在执行 y = *x 语句时检测无效的指针访问,并且报告错误:


# dtrace -s badptr.d
dtrace: script '/dev/stdin' matched 1 probe
CPU     ID                    FUNCTION:NAME
dtrace: error on enabled probe ID 1 (ID 1: dtrace:::BEGIN): invalid address
(0x0) in action #2 at DIF offset 4
dtrace: 1 error on CPU 0
^C
#

使用无效指针的程序可能产生的另一个问题就是对齐错误。按照体系结构约定,基础数据对象(如整数)将根据大小在内存中对齐。例如,2 字节整数在 2 的倍数的地址上对齐,4 字节整数在 4 的倍数的地址上对齐,依此类推。如果对指向 4 字节整数的指针取消引用,并且指针地址是无效值(不是 4 的倍数),则访问将失败,并且产生对齐错误。D 中的对齐错误几乎都是指示:指针因为 D 程序中的错误而包含无效的值或损坏的值。可通过将 badptr.d 的源代码更改为使用地址 (int *)2 而不是 NULL 来创建示例对齐错误。因为 int 是 4 字节,并且 2 不是 4 的倍数,所以表达式 *x 将导致 DTrace 对齐错误。

有关 DTrace 错误机制的详细信息,请参见ERROR 探测器