子例程与操作不同,因为子例程通常仅会影响 DTrace 的内部状态。因此,没有破坏性的子例程,并且子例程从不会跟踪数据到缓冲区中。在 9F 或 3C 一节的接口中,许多子例程都有相应的模拟程序。有关相应子例程的更多信息,请参见 Intro(9F) 和 Intro(3)。
void *alloca(size_t size)
alloca() 在临时空间外部分配 size 个字节,并返回指向已分配内存的指针。返回的指针一定是每 8 个字节对齐的。临时空间仅在子句的持续时间中有效。使用 alloca() 分配的内存在子句完成时将解除分配。如果没有可用的足够临时空间,将不会分配内存,并且将生成错误。
string basename(char *str)
basename() 是 basename(1) 的 D 类似程序。此子例程创建一个包含所指定字符串的副本的字符串,但该字符串不包含以 / 结尾的任何前缀。返回的字符串分配到临时内存外部,因此它们仅在子句的持续时间中有效。如果没有可用的足够临时空间,则不会执行 basename,并且将生成错误。
void bcopy(void *src, void *dest, size_t size)
bcopy() 从 src 指向的内存复制 size 字节到 dest 指向的内存。所有源内存都必须位于临时内存外部,所有目标内存都必须位于临时内存中。如果不满足这些条件,则不会进行复制操作,并且将生成错误。
string cleanpath(char *str)
cleanpath() 创建包含由 str 表示的路径副本的字符串,但该字符串删除了某些多余元素。需要特别指出的是,路径中的 "/./" 元素已删除,并且 "/../" 元素已折叠。折叠路径中的 /../ 元素时将不考虑符号链接。因此,cleanpath() 可能会采用有效路径,但返回更短的无效路径。
例如,如果 str 为 "/foo/../bar" 且 /foo 为指向 /net/foo/export 的符号链接,则 cleanpath() 将返回字符串 "/bar",即使 bar 可能仅位于 /net/foo 中而不是 / 中。作出此限制是因为,cleanpath() 在触发探测器的上下文中调用,在此情况下不能进行完整的符号链接解析或使用任意名称。返回的字符串分配到临时内存外部,因此它们仅在子句的持续时间中有效。如果没有可用的足够临时空间,则不会执行 cleanpath,并且将生成错误。
void *copyin(uintptr_t addr, size_t size)
copyin() 从指定的用户地址中复制指定的字节大小到 DTrace 临时缓冲区中,并返回此缓冲区的地址。用户地址解释为与当前线程关联的进程空间中的地址。生成的缓冲区指针一定是每 8 个字节对齐的。有问题的地址必须与当前进程中的错误页面对应。如果地址与错误页面不对应,或者没有可用的足够临时空间,则会返回 NULL,并且将生成错误。有关降低出现 copyin 错误可能性的方法,请参见第 33 章。
string copyinstr(uintptr_t addr)
copyinstr() 从指定的用户地址中复制以 null 结尾的 C 字符串到 DTrace 临时缓冲区中,并返回此缓冲区的地址。用户地址解释为与当前线程关联的进程空间中的地址。字符串长度限于由 strsize 选项指定的值;有关详细信息,请参见第 16 章。与 copyin 一样,指定的地址必须与当前进程中的错误页面对应。如果地址与错误页面不对应,或者没有可用的足够临时空间,则会返回 NULL,并且将生成错误。有关降低出现 copyinstr 错误可能性的方法,请参见第 33 章。
void copyinto(uintptr_t addr, size_t size, void *dest)
copyinto() 从指定的用户地址中复制指定的字节大小到 dest 指定的 DTrace 临时缓冲区中。用户地址解释为与当前线程关联的进程空间中的地址。有问题的地址必须与当前进程中的错误页面对应。如果地址与错误页面不对应,或者任何目标内存位于临时空间外部,则不会进行复制操作,并且将生成错误。有关降低出现 copyinto 错误可能性的方法,请参见第 33 章。
string dirname(char *str)
dirname() 是 dirname(1) 的 D 类似程序。此子例程创建一个字符串,该字符串包含除 str 指定的最后一级路径名之外的所有内容。返回的字符串分配到临时内存外部,因此它们仅在子句的持续时间中有效。如果没有可用的足够临时内存,则不会执行 dirname,并且将生成错误。
size_t msgdsize(mblk_t *mp)
msgdsize() 返回由 mp 指向的数据消息中的字节数。有关详细信息,请参见 msgdsize(9F)。msgdsize() 在计数中仅包括 M_DATA 类型的数据块。
size_t msgsize(mblk_t *mp)
msgsize() 返回由 mp 指向的消息中的字节数。与 msgdsize()(仅返回数据字节数)不同,msgsize() 返回消息中字节的总数。
int mutex_owned(kmutex_t *mutex)
mutex_owned() 是 mutex_owned(9F) 的实现。如果调用线程当前拥有指定的内核互斥,则 mutex_owned() 将返回非零值;如果调用线程当前不拥有指定的自适应互斥,则将返回零。
kthread_t *mutex_owner(kmutex_t *mutex)
mutex_owner() 返回所指定自适应内核互斥的当前属主的线程指针。如果当前不拥有指定的自适应互斥,或者指定的互斥为自旋互斥,则 mutex_owner() 将返回 NULL。请参见 mutex_owned(9F)。
int mutex_type_adaptive(kmutex_t *mutex)
如果指定的内核互斥为 MUTEX_ADAPTIVE 类型,则 mutex_type_adaptive() 将返回非零值,如果不是该类型,则将返回零。如果互斥满足以下一个或多个条件,则它们是自适应的:
互斥以静态方式声明
互斥使用 NULL 的中断块 cookie 创建
互斥使用与高级中断不对应的中断块 cookie 创建
有关互斥的更多详细信息,请参见 mutex_init(9F)。Solaris 内核中的大多数互斥都是自适应的。
int progenyof(pid_t pid)
如果调用进程(与当前正在触发匹配探测器的线程关联的进程)是指定进程 ID 的子孙,则 progenyof() 将返回非零值。
int rand(void)
rand() 返回伪随机整数。返回的数字为脆弱的伪随机数,不应用于任何加密应用程序。
int rw_iswriter(krwlock_t *rwlock)
如果指定的读取器-写入器锁定由写入者拥有或者写入者希望获取该锁,则 rw_iswriter() 将返回非零值。如果仅读取者拥有该锁,并且未阻止任何写入者;或者根本不拥有该锁,则 rw_iswriter() 将返回零。请参见 rw_init(9F)。
int rw_write_held(krwlock_t *rwlock)
如果指定的读取器-写入器锁定当前由写入者拥有,则 rw_write_held() 将返回非零值。如果仅读取者拥有该锁,或者根本不拥有该锁,则 rw_write_held() 将返回零。请参见 rw_init(9F)。
int speculation(void)
speculation() 将推理跟踪缓冲区保留用于 speculate(),并返回此缓冲区的标识符。有关详细信息,请参见第 13 章。
string strjoin(char *str1, char *str2)
strjoin() 创建一个字符串,该字符串包含 str1 与 str2 的串连。返回的字符串分配到临时内存外部,因此它们仅在子句的持续时间中有效。如果没有可用的足够临时空间,则不会执行 strjoin,并且将生成错误。
size_t strlen(string str)