# 27.2.实现上的差异

虽然 FreeBSD 中的 DTrace 与 Solaris™ 中的类似，但仍存在一些差异。最主要的区别是，在 FreeBSD 中，DTrace 以一组内核模块的形式实现，模块加载之前无法使用 DTrace。要加载所有必要的模块，可以执行：

```sh
# kldload dtraceall
```

从 FreeBSD 10.0-RELEASE 开始，当运行 [dtrace(1)](https://man.freebsd.org/cgi/man.cgi?query=dtrace\&sektion=1\&format=html) 时，这些模块会自动加载。

FreeBSD 使用 `DDB_CTF` 内核选项来支持从内核模块及内核本身加载 [ctf(5)](https://man.freebsd.org/cgi/man.cgi?query=ctf\&sektion=5\&format=html) 数据。`CTF` 是 Solaris™ 的 Compact C Type Format，用于封装简化的调试信息，类似于 `DWARF` 或传统的 stabs。`CTF` 数据由 [ctfconvert(1)](https://man.freebsd.org/cgi/man.cgi?query=ctfconvert\&sektion=1\&format=html) 和 [ctfmerge(1)](https://man.freebsd.org/cgi/man.cgi?query=ctfmerge\&sektion=1\&format=html) 构建工具添加到二进制文件中。`ctfconvert` 工具解析编译器生成的 `DWARF` `ELF` 调试段，而 `ctfmerge` 将对象文件中的 `CTF` `ELF` 段合并到可执行文件或共享库中。

FreeBSD 提供的 provider 与 Solaris™ 略有不同。其中最值得注意的是 `dtmalloc` provider，它允许在 FreeBSD 内核中按类型跟踪 [malloc(9)](https://man.freebsd.org/cgi/man.cgi?query=malloc\&sektion=9\&format=html)。某些 Solaris™ 中的 provider（如 `cpc`）在 FreeBSD 中不存在，但可能会出现在未来版本中。此外，两者均存在的 provider 可能不兼容，其探针的参数类型不同。因此，在 Solaris™ 上编写的 D 脚本在 FreeBSD 上可能需要修改才能运行，反之亦然。

由于安全机制的不同，FreeBSD 上只有 `root` 用户可以使用 DTrace。Solaris™ 中存在一些低级安全检查，而 FreeBSD 尚未实现。因此，**/dev/dtrace/dtrace** 严格限制为 `root` 使用。

DTrace 属于通用开发与分发许可 (`CDDL`) 下的开源软件。在 FreeBSD 上查看该许可，请参阅 **/usr/src/cddl/contrib/opensolaris/OPENSOLARIS.LICENSE**，或在线查看 <http://opensource.org/licenses/CDDL-1.0>。虽然内核自带 DTrace 支持的 FreeBSD 是 `BSD` 许可，但当模块以二进制形式分发或加载二进制文件时，会使用 `CDDL` 许可。
