-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Treat go binaries without offsets as generic #1476
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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} | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is actually not enough to fix this issue. The Go proxy checks for functions missing, not offsets for fields. |
||
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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should not be here, it will print a warning for our users in their logs for every go executable we discover which doesn't have any functions we care about. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This particular bit relates to this:
It's a very corner case, not present in the reported issue but I discovered it while analysing the code. If offsets are null (and thus There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah I see now, okay makes sense. |
||
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) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the only thing we need to do to fix and include a check that will avoid the null pointer in go tracers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe there's more to it. This lies in the case when We opted to leave this in the PR because this fixes the issue you are talking about, but I reckon that happens to be a different issue. |
||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we just need this check IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that may work indeed, but we end up being less robust by losing the distinction of the corner case (not directly related to the reported issue) in which we end up with a binary having
.gosymtabs
but no symbols. With the present code, we print a "prettier" message.We still need to set the error here if you want to print a proper message when we find go proxies though.