Skip to content

Commit

Permalink
symbolication: allow symbol upload for Bazel-built Go binairies (#57)
Browse files Browse the repository at this point in the history
Bazel built Go binairies have their GNU build ID stripped, and
their Go build ID set to the string "redacted"
See https://github.com/bazelbuild/rules_go/blob/199d8e4827f87d382a85febd0148c1b42fa949cc/go/private/actions/link.bzl#L174

In that case, we want to able to rely on the file hash, for this
reason we:
- modify the function to get go build ID to consider that "redacted"
is equivalent to not having a build ID
- still upload debug symbols even if they don't contain a GNU build
id or a Go build ID (they'll always contain a file hash, that
we will be using for symbolication in that case).

The underlying goal is to allow remote symbolication with local
symbol upload to work seamless for Go binaries built with Bazel
  • Loading branch information
Gandem authored Sep 4, 2024
1 parent ec00b6a commit 5d1ecca
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 13 deletions.
7 changes: 6 additions & 1 deletion libpf/pfelf/pfelf.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,18 @@ func GetGoBuildID(elfFile *elf.File) (string, error) {
}

// getGoBuildIDFromNotes returns the Go build ID from an ELF notes section data.
//
//nolint:lll
func getGoBuildIDFromNotes(notes []byte) (string, error) {
// 0x4 is the "Go Build ID" type. Not sure where this is standardized.
buildID, found, err := getNoteString(notes, "Go", 0x4)
if err != nil {
return "", fmt.Errorf("could not determine BuildID: %v", err)
}
if !found {
// When building Go binaries, Bazel explicitly sets their build ID to "redacted"
// see https://github.com/bazelbuild/rules_go/blob/199d8e4827f87d382a85febd0148c1b42fa949cc/go/private/actions/link.bzl#L174.
// In that case, we don't want to associate the build ID with the binary in the mapping.
if !found || buildID == "redacted" {
return "", ErrNoBuildID
}
return buildID, nil
Expand Down
20 changes: 8 additions & 12 deletions symbolication/datadog_uploader.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,7 @@ func (d *DatadogUploader) HandleExecutable(elfRef *pfelf.Reference, fileID libpf
return
}

e, err := newExecutableMetadata(fileName, ef, fileID)
if err != nil {
log.Debugf("Skipping symbol upload for executable %s: %v", fileName, err)
return
}
e := newExecutableMetadata(fileName, ef, fileID)

d.uploadCache.Add(fileID, struct{}{})
// TODO:
Expand Down Expand Up @@ -162,21 +158,21 @@ type executableMetadata struct {
}

func newExecutableMetadata(fileName string, elf *pfelf.File,
fileID libpf.FileID) (*executableMetadata, error) {
fileID libpf.FileID) *executableMetadata {
isGolang := elf.IsGolang()

buildID, err := elf.GetBuildID()
// Some Go executables don't have a GNU build ID, so we don't want to fail
// if we can't get it
if err != nil && !isGolang {
return nil, fmt.Errorf("failed to get build id: %w", err)
if err != nil {
log.Debugf(
"Unable to get GNU build ID for executable %s: %s", fileName, err)
}

goBuildID := ""
if isGolang {
goBuildID, err = elf.GetGoBuildID()
if err != nil {
return nil, fmt.Errorf("failed to get go build id: %w", err)
log.Debugf(
"Unable to get Go build ID for executable %s: %s", fileName, err)
}
}

Expand All @@ -191,7 +187,7 @@ func newExecutableMetadata(fileName string, elf *pfelf.File,
SymbolSource: "debug_info",
FileName: filepath.Base(fileName),
filePath: fileName,
}, nil
}
}

func (e *executableMetadata) String() string {
Expand Down

0 comments on commit 5d1ecca

Please sign in to comment.