From 7664338d24e01d8b47da1b0b8fac6ad9f097e572 Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Sat, 21 Dec 2024 15:42:55 -0600 Subject: [PATCH] Treat go binaries without offsets as generic (#1476) --- pkg/internal/discover/attacher.go | 4 +++- pkg/internal/discover/typer.go | 17 +++++++++++++++-- pkg/internal/goexec/structmembers.go | 2 +- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pkg/internal/discover/attacher.go b/pkg/internal/discover/attacher.go index 23fc892fd..b6d8632d0 100644 --- a/pkg/internal/discover/attacher.go +++ b/pkg/internal/discover/attacher.go @@ -134,9 +134,11 @@ func (ta *TraceAttacher) getTracer(ie *ebpf.Instrumentable) bool { case svc.InstrumentableGolang: // gets all the possible supported tracers for a go program, and filters out // those whose symbols are not present in the ELF functions list - if ta.Cfg.Discovery.SkipGoSpecificTracers || ta.Cfg.Discovery.SystemWide || ie.InstrumentationError != nil { + if ta.Cfg.Discovery.SkipGoSpecificTracers || ta.Cfg.Discovery.SystemWide || ie.InstrumentationError != nil || ie.Offsets == nil { if ie.InstrumentationError != nil { ta.log.Warn("Unsupported Go program detected, using generic instrumentation", "error", ie.InstrumentationError) + } else if ie.Offsets == nil { + ta.log.Warn("Go program with null offsets detected, using generic instrumentation") } if ta.reusableTracer != nil { // We need to do more than monitor PIDs. It's possible that this new diff --git a/pkg/internal/discover/typer.go b/pkg/internal/discover/typer.go index 00b23c7b4..8215b6709 100644 --- a/pkg/internal/discover/typer.go +++ b/pkg/internal/discover/typer.go @@ -1,6 +1,7 @@ package discover import ( + "fmt" "log/slog" "strings" @@ -124,6 +125,11 @@ func (t *typer) asInstrumentable(execElf *exec.FileInfo) ebpf.Instrumentable { instrumentableCache.Add(execElf.Ino, InstrumentedExecutable{Type: svc.InstrumentableGolang, Offsets: offsets}) return ebpf.Instrumentable{Type: svc.InstrumentableGolang, FileInfo: execElf, Offsets: offsets} } + + if err == nil { + err = fmt.Errorf("identified as a Go proxy") + } + log.Debug("identified as a Go proxy") } else { log.Debug("identified as a generic, non-Go executable") @@ -146,12 +152,19 @@ func (t *typer) asInstrumentable(execElf *exec.FileInfo) ebpf.Instrumentable { detectedType := exec.FindProcLanguage(execElf.Pid, execElf.ELF, execElf.CmdExePath) + if detectedType == svc.InstrumentableGolang && err == nil { + log.Warn("ELF binary appears to be a Go program, but no offsets were found", + "comm", execElf.CmdExePath, "pid", execElf.Pid) + + err = fmt.Errorf("could not find any Go offsets in Go binary %s", execElf.CmdExePath) + } + log.Debug("instrumented", "comm", execElf.CmdExePath, "pid", execElf.Pid, "child", child, "language", detectedType.String()) // Return the instrumentable without offsets, as it is identified as a generic // (or non-instrumentable Go proxy) executable - instrumentableCache.Add(execElf.Ino, InstrumentedExecutable{Type: detectedType, Offsets: offsets, InstrumentationError: err}) - return ebpf.Instrumentable{Type: detectedType, FileInfo: execElf, ChildPids: child, InstrumentationError: err} + instrumentableCache.Add(execElf.Ino, InstrumentedExecutable{Type: detectedType, Offsets: nil, InstrumentationError: err}) + return ebpf.Instrumentable{Type: detectedType, Offsets: nil, FileInfo: execElf, ChildPids: child, InstrumentationError: err} } func (t *typer) inspectOffsets(execElf *exec.FileInfo) (*goexec.Offsets, bool, error) { diff --git a/pkg/internal/goexec/structmembers.go b/pkg/internal/goexec/structmembers.go index a47cd1bd8..90ea2e769 100644 --- a/pkg/internal/goexec/structmembers.go +++ b/pkg/internal/goexec/structmembers.go @@ -443,7 +443,7 @@ func structMemberOffsetsFromDwarf(data *dwarf.Data) (FieldOffsets, map[GoOffset] log.Debug("inspecting fields for struct type", "type", typeName) if err := readMembers(reader, structMember.fields, expectedReturns, fieldOffsets); err != nil { log.Debug("error reading DWARF info", "type", typeName, "error", err) - return nil, expectedReturns + return fieldOffsets, expectedReturns } } }