diff --git a/internal/bpflbr/bpf_prog.go b/internal/bpflbr/bpf_prog.go index 36826e1..9890c0b 100644 --- a/internal/bpflbr/bpf_prog.go +++ b/internal/bpflbr/bpf_prog.go @@ -13,9 +13,7 @@ import ( type bpfProgs struct { progs map[ebpf.ProgramID]*ebpf.Program - infos map[ebpf.ProgramID]*bpfProgInfo - - ksyms map[uintptr]string + funcs map[uintptr]*bpfProgInfo // func IP -> prog info tracings map[string]bpfTracingInfo // id:func -> prog, func } @@ -23,9 +21,8 @@ type bpfProgs struct { func NewBPFProgs(engine gapstone.Engine, pflags []ProgFlag, onlyPrepare bool) (*bpfProgs, error) { var progs bpfProgs progs.progs = make(map[ebpf.ProgramID]*ebpf.Program, len(pflags)) - progs.infos = make(map[ebpf.ProgramID]*bpfProgInfo, len(pflags)) + progs.funcs = make(map[uintptr]*bpfProgInfo, len(pflags)) progs.tracings = make(map[string]bpfTracingInfo, len(pflags)) - progs.ksyms = make(map[uintptr]string) var err error defer func() { @@ -53,15 +50,12 @@ func NewBPFProgs(engine gapstone.Engine, pflags []ProgFlag, onlyPrepare bool) (* } func (b *bpfProgs) addProg(prog *ebpf.Program, id ebpf.ProgramID, engine gapstone.Engine) error { - var err error - b.infos[id], err = newBPFProgInfo(prog, engine) + progInfo, err := newBPFProgInfo(prog, engine) if err != nil { return fmt.Errorf("failed to create BPF program info for ID(%d): %w", id, err) } - info := b.infos[id].progs[0] - b.ksyms[info.kaddrRange.start] = info.funcName - + b.funcs[progInfo.progs[0].kaddrRange.start] = progInfo return nil } @@ -97,7 +91,7 @@ func (b *bpfProgs) Tracings() []bpfTracingInfo { } func (b *bpfProgs) get(addr uintptr) (*bpfProgLineInfo, bool) { - for _, info := range b.infos { + for _, info := range b.funcs { if line, ok := info.get(addr); ok { return line, true } diff --git a/internal/bpflbr/bpf_prog_info.go b/internal/bpflbr/bpf_prog_info.go index e70a925..4c9affb 100644 --- a/internal/bpflbr/bpf_prog_info.go +++ b/internal/bpflbr/bpf_prog_info.go @@ -142,3 +142,17 @@ func (b *bpfProgInfo) get(addr uintptr) (*bpfProgLineInfo, bool) { return nil, false } + +func (b *bpfProgInfo) contains(addr uintptr) bool { + for _, prog := range b.progs { + if addr >= prog.kaddrRange.start && addr < prog.kaddrRange.end { + return true + } + } + + return false +} + +func (b *bpfProgInfo) funcName() string { + return b.progs[0].funcName +} diff --git a/internal/bpflbr/lbr.go b/internal/bpflbr/lbr.go index 06958bb..33473f6 100644 --- a/internal/bpflbr/lbr.go +++ b/internal/bpflbr/lbr.go @@ -56,6 +56,12 @@ func Run(reader *ringbuf.Reader, progs *bpfProgs, addr2line *Addr2Line, ksyms *K continue } + progInfo, ok := progs.funcs[event.FuncIP] + if !ok { + continue + } + + foundEntries := false nrEntries := event.NrBytes / int64(8*3) lbrEntries := make([]branchEntry, 0, nrEntries) for i := 0; i < int(nrEntries); i++ { @@ -64,9 +70,14 @@ func Run(reader *ringbuf.Reader, progs *bpfProgs, addr2line *Addr2Line, ksyms *K break } - from := getLineInfo(entry.From, progs, addr2line, ksyms) - to := getLineInfo(entry.To, progs, addr2line, ksyms) - lbrEntries = append(lbrEntries, branchEntry{from, to}) + if foundEntries { + from := getLineInfo(entry.From, progs, addr2line, ksyms) + to := getLineInfo(entry.To, progs, addr2line, ksyms) + lbrEntries = append(lbrEntries, branchEntry{from, to}) + } else { + foundEntries = progInfo.contains(entry.From) || progInfo.contains(entry.To) + // Skip BPF/kprobe/perf internal entries. + } } if len(lbrEntries) == 0 { @@ -79,11 +90,7 @@ func Run(reader *ringbuf.Reader, progs *bpfProgs, addr2line *Addr2Line, ksyms *K stack.pushEntry(lbrEntries[i]) } - progName := progs.ksyms[event.FuncIP] - if progName == "" { - progName = fmt.Sprintf("UNKNOWN@%#x", event.FuncIP) - } - + progName := progInfo.funcName() fmt.Fprintf(&sb, "Recv a record for %s with retval=%d :\n", progName, event.Retval) stack.output(&sb) fmt.Fprintln(w, sb.String())