这是一个简单的bpftrace脚本:
#!/usr/bin/env bpftrace
tracepoint:syscalls:sys_enter_kill
{
$tpid = args->pid;
printf("%d %d %d\n", $tpid, $tpid < 0, $tpid >= 0);
}
它跟踪kill
系统调用,打印目标PID和两个附加值:它是否为负,以及是否为非负。
这是我得到的输出:
# ./test.bt
Attaching 1 probe...
-1746 0 1
-2202 0 1
4160 0 1
4197 0 1
4197 0 1
-2202 0 1
-1746 0 1
奇怪的是,对于比较运算符,正和负pid都显示为正。
出于理智,请检查我是否将分配行替换为:
$tpid = -10;
我得到的正是我所期望的:
# ./test.bt
Attaching 1 probe...
-10 1 0
-10 1 0
-10 1 0
我在做什么错?
正如您所发现的,bpftrace将u64
类型分配给$tpid
变量。但是,根据跟踪点格式文档,args->pid
应为pid_t
,or int
类型。
int
分配此类型的bpftrace函数为# cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_kill/format
name: sys_enter_kill
ID: 185
format:
field:unsigned short common_type; offset:0; size:2; signed:0;
field:unsigned char common_flags; offset:2; size:1; signed:0;
field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
field:int common_pid; offset:4; size:4; signed:1;
field:int __syscall_nr; offset:8; size:4; signed:1;
field:pid_t pid; offset:16; size:8; signed:0;
field:int sig; offset:24; size:8; signed:0;
print fmt: "pid: 0x%08lx, sig: 0x%08lx", ((unsigned long)(REC->pid)), ((unsigned long)(REC->sig))
。提交TracepointFormatParser::adjust_integer_types()
引入了此更改,以解决问题TracepointFormatParser::adjust_integer_types()
。
对于上面的跟踪点描述,bpftrace生成以下结构:
42ce08f
[应该在何时生成:
42ce08f
bpftrace似乎被与以上描述中的类型不匹配的size参数所混淆。所有syscall参数的大小均为8(至少在64位上),但这并不意味着所有8个字节都已使用。我认为值得在bpftrace上发布一个问题。
#124中的整数类型发生了一些奇怪的事情(有关详细信息,请参见struct _tracepoint_syscalls_sys_enter_kill
{
unsigned short common_type;
unsigned char common_flags;
unsigned char common_preempt_count;
int common_pid;
int __syscall_nr;
u64 pid;
s64 sig;
};
,struct _tracepoint_syscalls_sys_enter_kill
{
unsigned short common_type;
unsigned char common_flags;
unsigned char common_preempt_count;
int common_pid;
int __syscall_nr;
u32 pad1;
pid_t pid;
u32 pad2;
int sig;
};
,bpftrace
。
在我看来,#554默认情况下被视为64位值,而实际上不是。因此解决方案是显式转换它:
#772
现在它可以按预期工作:
#834