diff --git a/link/kprobe.go b/link/kprobe.go index 07bb51741..6e574af40 100644 --- a/link/kprobe.go +++ b/link/kprobe.go @@ -250,8 +250,9 @@ func pmuProbe(typ probeType, args probeArgs) (*perfEvent, error) { } var ( - attr unix.PerfEventAttr - sp unsafe.Pointer + attr unix.PerfEventAttr + sp unsafe.Pointer + token string ) switch typ { case kprobeType: @@ -261,6 +262,8 @@ func pmuProbe(typ probeType, args probeArgs) (*perfEvent, error) { return nil, err } + token = kprobeToken(args) + attr = unix.PerfEventAttr{ // The minimum size required for PMU kprobes is PERF_ATTR_SIZE_VER1, // since it added the config2 (Ext2) field. Use Ext2 as probe_offset. @@ -280,6 +283,8 @@ func pmuProbe(typ probeType, args probeArgs) (*perfEvent, error) { config |= args.refCtrOffset << uprobeRefCtrOffsetShift } + token = uprobeToken(args) + attr = unix.PerfEventAttr{ // The minimum size required for PMU uprobes is PERF_ATTR_SIZE_VER1, // since it added the config2 (Ext2) field. The Size field controls the @@ -299,26 +304,27 @@ func pmuProbe(typ probeType, args probeArgs) (*perfEvent, error) { // return -EINVAL. Return ErrNotSupported to allow falling back to tracefs. // https://github.com/torvalds/linux/blob/94710cac0ef4/kernel/trace/trace_kprobe.c#L340-L343 if errors.Is(err, unix.EINVAL) && strings.Contains(args.symbol, ".") { - return nil, fmt.Errorf("symbol '%s+%#x': older kernels don't accept dots: %w", args.symbol, args.offset, ErrNotSupported) + return nil, fmt.Errorf("token %s: older kernels don't accept dots: %w", token, ErrNotSupported) } // Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL // when trying to create a retprobe for a missing symbol. if errors.Is(err, os.ErrNotExist) { - return nil, fmt.Errorf("symbol '%s+%#x' not found: %w", args.symbol, args.offset, err) + return nil, fmt.Errorf("token %s: not found: %w", token, err) } // Since commit ab105a4fb894, EILSEQ is returned when a kprobe sym+offset is resolved // to an invalid insn boundary. The exact conditions that trigger this error are // arch specific however. if errors.Is(err, unix.EILSEQ) { - return nil, fmt.Errorf("symbol '%s+%#x' not found (bad insn boundary): %w", args.symbol, args.offset, os.ErrNotExist) + return nil, fmt.Errorf("token %s: bad insn boundary: %w", token, os.ErrNotExist) } // Since at least commit cb9a19fe4aa51, ENOTSUPP is returned // when attempting to set a uprobe on a trap instruction. if errors.Is(err, sys.ENOTSUPP) { - return nil, fmt.Errorf("failed setting uprobe on offset %#x (possible trap insn): %w", args.offset, err) + return nil, fmt.Errorf("token %s: failed setting uprobe on offset %#x (possible trap insn): %w", token, args.offset, err) } + if err != nil { - return nil, fmt.Errorf("opening perf event: %w", err) + return nil, fmt.Errorf("token %s: opening perf event: %w", token, err) } // Ensure the string pointer is not collected before PerfEventOpen returns. @@ -454,13 +460,15 @@ func createTraceFSProbeEvent(typ probeType, args probeArgs) error { pe = fmt.Sprintf("%s:%s/%s %s", probePrefix(args.ret), args.group, args.symbol, token) } _, err = f.WriteString(pe) + // Since commit 97c753e62e6c, ENOENT is correctly returned instead of EINVAL // when trying to create a retprobe for a missing symbol. if errors.Is(err, os.ErrNotExist) { return fmt.Errorf("token %s: not found: %w", token, err) } - // Since commit ab105a4fb894, -EILSEQ is returned when a kprobe sym+offset is resolved - // to an invalid insn boundary. + // Since commit ab105a4fb894, EILSEQ is returned when a kprobe sym+offset is resolved + // to an invalid insn boundary. The exact conditions that trigger this error are + // arch specific however. if errors.Is(err, syscall.EILSEQ) { return fmt.Errorf("token %s: bad insn boundary: %w", token, os.ErrNotExist) } @@ -469,8 +477,9 @@ func createTraceFSProbeEvent(typ probeType, args probeArgs) error { if errors.Is(err, syscall.ERANGE) { return fmt.Errorf("token %s: offset too big: %w", token, os.ErrNotExist) } + if err != nil { - return fmt.Errorf("writing '%s' to '%s': %w", pe, typ.EventsPath(), err) + return fmt.Errorf("token %s: writing '%s' to '%s': %w", token, pe, typ.EventsPath(), err) } return nil