diff --git a/libpf/symbol.go b/libpf/symbol.go index 81fd1ce54..dd3c490ae 100644 --- a/libpf/symbol.go +++ b/libpf/symbol.go @@ -82,15 +82,19 @@ func (symmap *SymbolMap) LookupSymbol(symbolName SymbolName) (*Symbol, error) { return nil, fmt.Errorf("symbol %v not present in map", symbolName) } -// LookupSymbolByPrefix loops over all known symbols and returns the first symbol -// that starts with the given prefix. -func (symmap *SymbolMap) LookupSymbolByPrefix(prefix string) (*Symbol, error) { +// LookupSymbolsByPrefix loops over all known symbols and returns all symbols +// that start with the given prefix. +func (symmap *SymbolMap) LookupSymbolsByPrefix(prefix string) ([]*Symbol, error) { + var symbols []*Symbol for name, sym := range symmap.nameToSymbol { if strings.HasPrefix(string(name), prefix) { - return sym, nil + symbols = append(symbols, sym) } } - return nil, fmt.Errorf("no symbol present that starts with '%s'", prefix) + if len(symbols) == 0 { + return nil, fmt.Errorf("no symbol present that starts with '%s'", prefix) + } + return symbols, nil } // LookupSymbolAddress returns the address of a symbol. diff --git a/tracer/tracer.go b/tracer/tracer.go index ad969dbe3..b48aa8177 100644 --- a/tracer/tracer.go +++ b/tracer/tracer.go @@ -1297,16 +1297,27 @@ func (t *Tracer) StartOffCPUProfiling() error { return errors.New("off-cpu program finish_task_switch is not available") } - kprobeSymbol, err := t.kernelSymbols.LookupSymbolByPrefix("finish_task_switch") + hookSymbolPrefix := "finish_task_switch" + kprobeSymbs, err := t.kernelSymbols.LookupSymbolsByPrefix(hookSymbolPrefix) if err != nil { - return errors.New("failed to find kernel symbol for finish_task_switch") + return err } - kprobeLink, err := link.Kprobe(string(kprobeSymbol.Name), kprobeProg, nil) - if err != nil { - return err + attached := false + // Attach to all symbols with the prefix finish_task_switch. + for _, symb := range kprobeSymbs { + kprobeLink, linkErr := link.Kprobe(string(symb.Name), kprobeProg, nil) + if linkErr != nil { + log.Warnf("Failed to attach to %s: %v", symb.Name, linkErr) + continue + } + attached = true + t.hooks[hookPoint{group: "kprobe", name: string(symb.Name)}] = kprobeLink + } + if !attached { + return fmt.Errorf("failed to attach to one of %d symbols with prefix '%s'", + len(kprobeSymbs), hookSymbolPrefix) } - t.hooks[hookPoint{group: "kprobe", name: "finish_task_switch"}] = kprobeLink // Attach the first hook that enables off-cpu profiling. tpProg, ok := t.ebpfProgs["tracepoint__sched_switch"]