我们可以像函数一样转储用户空间函数的函数参数 在内核空间?如果我们,FBT提供程序可以转储用户空间函数的参数 做dtrace -l -f -v?
我是DTrace'ing“顶级”实用程序,(“顶级”实用程序都有 在目标文件中构建的CTF和Dwarf调试部分
我正在尝试检查“top”调用的get_system_info函数,我 确认它有待探测
root% dtrace -l | grep get_system_info
55154 pid8488 top get_system_info entry
但我无法将参数转储到函数...
root% dtrace -l -f get_system_info -v
ID PROVIDER MODULE FUNCTION NAME
55154 pid8488 top get_system_info entry
Probe Description Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: Unknown
Argument Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: Unknown
Argument Types
None
使用简单的脚本进行测试
pid8488::get_system_info:entry
{
this->info = (struct system_info *)copyin(args[0], sizeof(struct system_info));
}
...如果我使用args [0]表示法,则说明以下内容,
dtrace: failed to compile script top_d.d: line 17: index 0 is out of
range for pid8488::get_system_info:entry args[ ]
相反,如果我用arg0替换它,它会编译,但值不是 一定是理智的。 示例struct system_info的ncpus成员显示垃圾值。
完整的脚本是
pid8488::get_system_info:entry
{
this->info = (struct system_info *)copyin(arg0, sizeof(struct system_info));
printf("last pid [%d] \n", this->info->last_pid);
}
pid8488::get_process_info:entry
{
this->info = (struct system_info *)copyin(arg0, sizeof(struct system_info));
printf("ncpus [%d] \n", this->info->ncpus);
}
运行此
55154 get_system_info:entry last pid [8513]
55155 get_process_info:entry ncpus [134558720]
假设显示cpus的数量?脚本有什么问题吗?
答案 0 :(得分:0)
我曾经在9.1和9.2-RC2上调查过这个问题,但我无法让DTrace正常工作,所以我的评论基于Solaris版本,这应该大致相当。
fbt提供者仪器内核函数。它的用户土地等价物是pid提供者。
pid提供程序当然可以公开函数参数,但是,除非FreeBSD的DTrace支持用户区CTF,否则它们的类型将不可用。这可能是您发现键入的args[n]
不可用而且您被限制为整数argn
的原因。
我猜测函数get_system_info()
会填充struct system_info
。如果是这种情况,那么您必须在从函数返回后的结构中复制。
此外,如果dtrace(1)找不到该结构的定义,那么您必须自己提供它,包括它或适当的头文件(并使用-C
标志)。
这是一个(未经测试的)示例:
struct system_info { ... unsigned int ncpus; ... }; pid$target::get_system_info:entry { self->siup = (uintptr_t)arg0; /* user-land pointer */ } pid$target::get_system_info:return /self->siup/ { this->sikp = (struct system_info *) /* kernel pointer */ copyin(self->siup, sizeof (struct system_info)); printf("ncpus = %d\n", this->sikp->ncpus); self->siup = 0; /* free thread-local storage */ }
最后,在评估数据类型(例如指针大小)时,dtrace(1)将会
默认为正在运行的内核的数据模型。如果您正在运行64位内核,但是您正在使用32位进程,则使用“-32
”标志,以便dtrace(1)对其看到的各种类型使用适当的大小。