为何调用bpf_get_current_task()获取的pid字段始终返回0?
问题分析与修正
你的代码存在两个核心问题,导致获取的PID始终为0:
1. 直接访问内核结构体字段的风险
内核BPF验证器会严格限制对内核结构体的直接内存访问,不同Linux内核版本中task_struct的字段偏移可能发生变化,直接读取task->pid会访问到错误的内存地址,最终得到无效的0值。这种访问方式甚至可能被验证器拦截,只是bcc在此场景下未抛出明确错误。
2. 混淆线程ID与进程ID的定义
Linux内核中,task_struct->pid对应的是线程ID(TID),而我们日常所说的进程ID(PID)实际是线程组ID,对应task_struct->tgid字段。即便你能正确读取pid字段,得到的也不是目标进程ID。
修正后的代码
使用BPF标准辅助函数bpf_get_current_pid_tgid()安全获取进程ID与线程ID,该函数返回一个64位数值:
- 低32位:线程ID(TID)
- 高32位:进程ID(PID,即线程组ID)
#!/usr/bin/python3 from bcc import BPF program = ''' int hello_world(void* ctx){ u64 pid_tgid = bpf_get_current_pid_tgid(); // 提取高32位作为进程ID u32 pid = pid_tgid >> 32; bpf_trace_printk("pid is %d\\n", pid); return 0; } ''' p = BPF(text=program) syscall = p.get_syscall_fnname("execve") p.attach_kprobe(event=syscall, fn_name="hello_world") p.trace_print()
额外说明
若需要获取线程ID,可提取低32位数值:
u32 tid = pid_tgid & 0xFFFFFFFF;
内容的提问来源于stack exchange,提问作者SolskGaer
相关产品推荐
相关产品推荐

