eBPF 프로그램에서 커널 스택 추적을 얻을 때 중복되고 이상한 항목이 나타납니다. 누군가 이것을 설명할 수 있습니까?
먼저 관련 eBPF 프로그램 조각부터 시작하겠습니다. 다음과 같이 스택 추적 그래프를 선언합니다.
struct {
__uint(type, BPF_MAP_TYPE_STACK_TRACE);
__type(key, u32);
__type(value, stack);
__uint(max_entries, 1 << 14);
} stacks SEC(".maps");
나중에 첨부할 eBPF 프로그램에서 cap_capable
다음과 같이 스택 추적을 저장한 다음 스택 추적 ID를 사용자 공간으로 보냅니다.
kstackid = bpf_get_stackid(ctx, &stacks, 0);
Go의 사용자 공간 측면에서 Cilium을 사용하는 것이 매우 유용합니다.ebpf Go 모듈. 특정 스택 추적에 대한 명령 포인터를 읽으려면 다음을 수행합니다.
ips := make([]uint64, MaxStackDepth)
if err := objs.Stacks.Lookup(event.Kstackid, ips); err != nil {
slog.Error("looking up kernel stack trace", "error", err)
continue
}
l := len(ips)
for idx, ip := range ips {
if ip == 0 {
l = idx
break
}
}
ev := Event{
bpfCapevent: event,
KernelStack: ips[:l],
}
이제 데이터를 사용하여 명령 포인터를 구문 분석하면 /proc/kallsyms
IP도 표시하는 다음과 같은 스택이 생성됩니다.
bpf_prog_47f71ae01d77a0b5_fentry_cap_capable ffffffffc00860ed
bpf_prog_47f71ae01d77a0b5_fentry_cap_capable ffffffffc00860ed
udp_tunnel_nic_init_module ffffffffc0e2004f
cap_capable ffffffff9ea9b1a5
- 왜 거기에 있습니까?둘Fentry의 IP 주소는 무엇입니까
cap_capable
? 둘 다 동일한 반송 주소인데 여기서 무슨 일이 일어나고 있는 걸까요? cap_capable
내 eBPF 프로그램 사이의 중간 기능은 무엇입니까udp_tunnel_nic_init_module
? 오해가 있는 것 같나요? 트램폴린과 관련이 있는걸까요...?