Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 7 additions & 27 deletions reporter/symbol/elf.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"fmt"
"os"
"runtime"
"sync/atomic"

log "github.com/sirupsen/logrus"
"go.opentelemetry.io/ebpf-profiler/libpf"
Expand Down Expand Up @@ -125,45 +124,26 @@ func (e *Elf) Close() {
}
}

var BiggestBinarySize int64

func updateBiggestBinarySize(size int64) {
for {
current := atomic.LoadInt64(&BiggestBinarySize)
if current >= size {
break
}
if atomic.CompareAndSwapInt64(&BiggestBinarySize, current, size) {
break
}
}
}

// GetSize returns the size of the elf file or data it contains.
// It will return 0 if the size can't be retrieved.
func (e *Elf) GetSize() int64 {
elfPath := e.SymbolPathOnDisk()
var size int64
// vdso
if elfPath == "" {
data, err := e.wrapper.ElfData()
if err != nil {
log.Warnf("Failed to get elf data: %v", err)
return 0
}
size = int64(len(data))
} else {
fi, err := os.Stat(elfPath)
if err != nil {
log.Warnf("Failed to get elf file: %v", err)
return 0
}
size = fi.Size()
return int64(len(data))
}

updateBiggestBinarySize(size)

return size
fi, err := os.Stat(elfPath)
if err != nil {
log.Warnf("Failed to get elf file: %v", err)
return 0
}
return fi.Size()
}

func (e *Elf) SymbolSource() Source {
Expand Down
35 changes: 24 additions & 11 deletions reporter/symbol_uploader.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ type DatadogSymbolUploader struct {
retrievalQueue chan *reporter.ExecutableMetadata
pipeline pipeline.Pipeline[*reporter.ExecutableMetadata]
mut sync.Mutex
biggestBinarySize int64
}

type goPCLnTabDump struct {
Expand Down Expand Up @@ -197,7 +198,7 @@ func (d *DatadogSymbolUploader) Start(ctx context.Context) {
func(elfSymbols ElfWithBackendSources) int64 {
size := elfSymbols.GetSize()
if size > memoryBudget {
log.Warnf("Upload size is larger than memory limit, attempting upload if %v", elfSymbols)
log.Warnf("Upload size is larger than memory limit, attempting upload of %v", elfSymbols)
size = memoryBudget
}
return size
Expand Down Expand Up @@ -449,6 +450,18 @@ func newSymbolUploadRequestMetadata(e *symbol.Elf, symbolSource symbol.Source, p
}
}

func (d *DatadogSymbolUploader) updateBiggestBinarySize(size int64) {
for {
current := atomic.LoadInt64(&d.biggestBinarySize)
if current >= size {
break
}
if atomic.CompareAndSwapInt64(&d.biggestBinarySize, current, size) {
break
}
}
}

func (d *DatadogSymbolUploader) createSymbolFile(ctx context.Context, e *symbol.Elf) (*os.File, error) {
symbolFile, err := os.CreateTemp("", "objcopy-debug")
if err != nil {
Expand Down Expand Up @@ -481,9 +494,17 @@ func (d *DatadogSymbolUploader) createSymbolFile(ctx context.Context, e *symbol.
sectionsToKeep = e.GetSectionsRequiredForDynamicSymbols()
}

// keep track of the biggest binary size we try to upload for logging purposes
d.updateBiggestBinarySize(e.GetSize())
err = CopySymbols(ctx, elfPath, symbolFile.Name(), goPCLnTabInfo, sectionsToKeep, d.compressDebugSections)

if err != nil {
return nil, fmt.Errorf("failed to copy symbols: %w", err)
var ExitError *exec.ExitError
if errors.As(err, &ExitError) && ExitError.ExitCode() == -1 { // killed by signal
return nil, fmt.Errorf("failed to copy symbols: got killed. Consider increasing memory limits to at least %v (biggest uncompressed elf file size found)", atomic.LoadInt64(&d.biggestBinarySize))
}

return nil, fmt.Errorf("failed to copy symbols: failed to extract debug symbols: %w", cleanCmdError(err))
}

return symbolFile, nil
Expand Down Expand Up @@ -587,15 +608,7 @@ func CopySymbols(ctx context.Context, inputPath, outputPath string, goPCLnTabInf
log.Warnf("Could not adjust OOM score: %v", err)
}

if err := cmd.Wait(); err != nil {
var ExitError *exec.ExitError
if errors.As(err, &ExitError) && ExitError.ExitCode() == -1 { // killed by signal
return fmt.Errorf("got killed. Consider increasing memory limits to at least %v (biggest uncompressed elf file size found)", atomic.LoadInt64(&symbol.BiggestBinarySize))
}
return fmt.Errorf("failed to extract debug symbols: %w", cleanCmdError(err))
}

return nil
return cmd.Wait()
}

func (d *DatadogSymbolUploader) uploadSymbols(ctx context.Context, symbolFilePath string, e *symbolUploadRequestMetadata, endpointIdx int) error {
Expand Down