From 0d27b95636b9a9963e94ec5e06dc6a995016490c Mon Sep 17 00:00:00 2001 From: ltrk2 <107155950+ltrk2@users.noreply.github.com> Date: Wed, 4 Dec 2024 12:34:19 -0500 Subject: [PATCH] Sync from upstream (2024-12-03) (#5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix unwinding at syscall on aarch64 (#218) * Add PID as an attribute in each sample (#212) * ebpf: increase number of stack delta buckets (#231) Signed-off-by: Florian Lehner * reporter: use htlhash attribute for profiling specific hash (#236) Signed-off-by: Florian Lehner * reporter: drop fifo (#239) Signed-off-by: Florian Lehner * Drop more unused code (#240) * reporter: do not add empty attributes (#233) Signed-off-by: Florian Lehner * controller: fix reporter interval mix up with monitor interval (#242) * Extract reporter runloop (#228) Co-authored-by: Christos Kalkanis * Extract lookupcgroupv2 out of the otlp reporter (#227) * Add CPU id to trace and trace metadata (#249) * reporter: don't expire actively used executables (#247) * Remove legacy code from libpf.UnixTime64 (#252) * Turn kernel module file parsing errors into warnings (#255) Co-authored-by: Florian Lehner * readatbuf: add missing check when reading from tail chunk (#259) * metrics: Don't send counters with 0 values (#246) --------- Signed-off-by: Florian Lehner Co-authored-by: umanwizard Co-authored-by: Bhavna Jindal Co-authored-by: Florian Lehner Co-authored-by: Tim Rühsen Co-authored-by: Nayef Ghattas Co-authored-by: Damien Mathieu <42@dmathieu.com> Co-authored-by: Christos Kalkanis Co-authored-by: Tommy Reilly Co-authored-by: Joel Höner --- README.md | 4 +- go.mod | 5 +- go.sum | 8 +- host/host.go | 1 + internal/controller/controller.go | 4 +- libpf/cgroupv2.go | 59 ++++++++ libpf/convenience.go | 20 --- libpf/libpf.go | 31 +--- libpf/libpf_test.go | 35 ----- libpf/pfelf/pfelf.go | 126 --------------- libpf/readatbuf/readatbuf.go | 3 + libpf/readatbuf/readatbuf_test.go | 16 ++ libpf/tracehash.go | 9 -- main.go | 2 +- metrics/metrics.go | 19 +++ metrics/metrics_test.go | 5 + proc/proc.go | 9 +- processmanager/ebpf/ebpf.go | 2 + processmanager/ebpf/ebpf_test.go | 11 +- reporter/fifo.go | 122 --------------- reporter/fifo_test.go | 118 --------------- reporter/iface.go | 1 + reporter/otlp_reporter.go | 202 ++++++++++--------------- reporter/otlp_reporter_test.go | 55 +++++-- reporter/runloop.go | 44 ++++++ stringutil/stringutil.go | 5 - support/ebpf/dotnet_tracer.ebpf.c | 2 +- support/ebpf/extmaps.h | 2 + support/ebpf/hotspot_tracer.ebpf.c | 4 +- support/ebpf/native_stack_trace.ebpf.c | 16 +- support/ebpf/tracemgmt.h | 20 +++ support/ebpf/tracer.ebpf.release.amd64 | Bin 297824 -> 299160 bytes support/ebpf/tracer.ebpf.release.arm64 | Bin 289904 -> 291032 bytes support/ebpf/types.h | 17 ++- support/ebpf/v8_tracer.ebpf.c | 2 +- tools/coredump/ebpfhelpers.go | 3 +- tracehandler/tracehandler.go | 1 + tracer/events.go | 4 +- tracer/tracer.go | 7 +- 39 files changed, 362 insertions(+), 632 deletions(-) create mode 100644 libpf/cgroupv2.go delete mode 100644 reporter/fifo.go delete mode 100644 reporter/fifo_test.go create mode 100644 reporter/runloop.go diff --git a/README.md b/README.md index 5f3c1bd1..3922aa8a 100644 --- a/README.md +++ b/README.md @@ -91,9 +91,9 @@ devfiler spins up a local server that listens on `0.0.0.0:11000`. To run it, simply download and unpack the archive from the following URL: -https://upload.elastic.co/d/87e7697991940ec37f0c6e39ac38d213f65e8dc1ef9dbedff6aab9cba0adfaba +https://upload.elastic.co/d/f8aa0c386baa808a616ca29f86b34c726edb5af36f8840a4cf28468ad534a4b5 -Authentication token: `c74dfc4db2212015` +Authentication token: `2635c0750bf8ea69` The archive contains a build for each of the following platforms: diff --git a/go.mod b/go.mod index d94fc264..145446b0 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,12 @@ module go.opentelemetry.io/ebpf-profiler go 1.22.2 require ( + github.com/aws/aws-sdk-go-v2 v1.30.5 github.com/aws/aws-sdk-go-v2/config v1.27.35 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.21 github.com/aws/aws-sdk-go-v2/service/s3 v1.62.0 github.com/cespare/xxhash/v2 v2.3.0 github.com/cilium/ebpf v0.16.0 - github.com/elastic/go-freelru v0.15.0 + github.com/elastic/go-freelru v0.16.0 github.com/elastic/go-perf v0.0.0-20241016160959-1342461adb4a github.com/google/uuid v1.6.0 github.com/jsimonetti/rtnetlink v1.4.2 @@ -29,7 +29,6 @@ require ( ) require ( - github.com/aws/aws-sdk-go-v2 v1.30.5 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.33 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13 // indirect diff --git a/go.sum b/go.sum index 10c61a9e..7fe300bb 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,6 @@ github.com/aws/aws-sdk-go-v2/credentials v1.17.33 h1:lBHAQQznENv0gLHAZ73ONiTSkCt github.com/aws/aws-sdk-go-v2/credentials v1.17.33/go.mod h1:MBuqCUOT3ChfLuxNDGyra67eskx7ge9e3YKYBce7wpI= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13 h1:pfQ2sqNpMVK6xz2RbqLEL0GH87JOwSxPV2rzm8Zsb74= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.13/go.mod h1:NG7RXPUlqfsCLLFfi0+IpKN4sCB9D9fw/qTaSB+xRoU= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.21 h1:sV0doPPsRT7gMP0BnDPwSsysVTV/nKpB/nFmMnz8goE= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.21/go.mod h1:ictvfJWqE2gkUFDRJVp5VU/TrytuzK88DYcpan7UYuA= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17 h1:pI7Bzt0BJtYA0N/JEC6B8fJ4RBrEMi1LBrkMdFYNSnQ= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17/go.mod h1:Dh5zzJYMtxfIjYW+/evjQ8uj2OyR/ve2KROHGHlSFqE= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 h1:Mqr/V5gvrhA2gvgnF42Zh5iMiQNcOYthFYwCyrnuWlc= @@ -43,10 +41,8 @@ github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEn github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/elastic/go-freelru v0.13.0 h1:TKKY6yCfNNNky7Pj9xZAOEpBcdNgZJfihEftOb55omg= -github.com/elastic/go-freelru v0.13.0/go.mod h1:bSdWT4M0lW79K8QbX6XY2heQYSCqD7THoYf82pT/H3I= -github.com/elastic/go-freelru v0.15.0 h1:Jo1aY8JAvpyxbTDJEudrsBfjFDaALpfVv8mxuh9sfvI= -github.com/elastic/go-freelru v0.15.0/go.mod h1:bSdWT4M0lW79K8QbX6XY2heQYSCqD7THoYf82pT/H3I= +github.com/elastic/go-freelru v0.16.0 h1:gG2HJ1WXN2tNl5/p40JS/l59HjvjRhjyAa+oFTRArYs= +github.com/elastic/go-freelru v0.16.0/go.mod h1:bSdWT4M0lW79K8QbX6XY2heQYSCqD7THoYf82pT/H3I= github.com/elastic/go-perf v0.0.0-20241016160959-1342461adb4a h1:ymmtaN4bVCmKKeu4XEf6JEWNZKRXPMng1zjpKd+8rCU= github.com/elastic/go-perf v0.0.0-20241016160959-1342461adb4a/go.mod h1:Nt+pnRYvf0POC+7pXsrv8ubsEOSsaipJP0zlz1Ms1RM= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= diff --git a/host/host.go b/host/host.go index c12a02a3..4b6a9d44 100644 --- a/host/host.go +++ b/host/host.go @@ -55,4 +55,5 @@ type Trace struct { TID libpf.PID APMTraceID libpf.APMTraceID APMTransactionID libpf.APMTransactionID + CPU int } diff --git a/internal/controller/controller.go b/internal/controller/controller.go index 12628306..17f796ef 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -56,8 +56,8 @@ func (c *Controller) Start(ctx context.Context) error { traceHandlerCacheSize := traceCacheSize(c.config.MonitorInterval, c.config.SamplesPerSecond, uint16(presentCores)) - intervals := times.New(c.config.MonitorInterval, - c.config.ReporterInterval, c.config.ProbabilisticInterval) + intervals := times.New(c.config.ReporterInterval, c.config.MonitorInterval, + c.config.ProbabilisticInterval) // Start periodic synchronization with the realtime clock times.StartRealtimeSync(ctx, c.config.ClockSyncInterval) diff --git a/libpf/cgroupv2.go b/libpf/cgroupv2.go new file mode 100644 index 00000000..aa5d952f --- /dev/null +++ b/libpf/cgroupv2.go @@ -0,0 +1,59 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package libpf // import "go.opentelemetry.io/ebpf-profiler/libpf" + +import ( + "bufio" + "fmt" + "os" + "regexp" + + lru "github.com/elastic/go-freelru" + log "github.com/sirupsen/logrus" +) + +var ( + cgroupv2PathPattern = regexp.MustCompile(`0:.*?:(.*)`) +) + +// LookupCgroupv2 returns the cgroupv2 ID for pid. +func LookupCgroupv2(cgrouplru *lru.SyncedLRU[PID, string], pid PID) (string, error) { + id, ok := cgrouplru.Get(pid) + if ok { + return id, nil + } + + // Slow path + f, err := os.Open(fmt.Sprintf("/proc/%d/cgroup", pid)) + if err != nil { + return "", err + } + defer f.Close() + + var genericCgroupv2 string + scanner := bufio.NewScanner(f) + buf := make([]byte, 512) + // Providing a predefined buffer overrides the internal buffer that Scanner uses (4096 bytes). + // We can do that and also set a maximum allocation size on the following call. + // With a maximum of 4096 characters path in the kernel, 8192 should be fine here. We don't + // expect lines in /proc//cgroup to be longer than that. + scanner.Buffer(buf, 8192) + var pathParts []string + for scanner.Scan() { + line := scanner.Text() + pathParts = cgroupv2PathPattern.FindStringSubmatch(line) + if pathParts == nil { + log.Debugf("Could not extract cgroupv2 path from line: %s", line) + continue + } + genericCgroupv2 = pathParts[1] + break + } + + // Cache the cgroupv2 information. + // To avoid busy lookups, also empty cgroupv2 information is cached. + cgrouplru.Add(pid, genericCgroupv2) + + return genericCgroupv2, nil +} diff --git a/libpf/convenience.go b/libpf/convenience.go index 02c7cae1..1abdb604 100644 --- a/libpf/convenience.go +++ b/libpf/convenience.go @@ -5,9 +5,7 @@ package libpf // import "go.opentelemetry.io/ebpf-profiler/libpf" import ( "context" - "fmt" "math/rand/v2" - "os" "reflect" "time" "unsafe" @@ -15,24 +13,6 @@ import ( log "github.com/sirupsen/logrus" ) -// WriteTempFile writes a data buffer to a temporary file on the filesystem. It -// is the callers responsibility to clean up that file again. The function returns -// the filename if successful. -func WriteTempFile(data []byte, directory, prefix string) (string, error) { - file, err := os.CreateTemp(directory, prefix) - if err != nil { - return "", err - } - defer file.Close() - if _, err := file.Write(data); err != nil { - return "", fmt.Errorf("failed to write data to temporary file: %w", err) - } - if err := file.Sync(); err != nil { - return "", fmt.Errorf("failed to synchronize file data: %w", err) - } - return file.Name(), nil -} - // SleepWithJitter sleeps for baseDuration +/- jitter (jitter is [0..1]) func SleepWithJitter(baseDuration time.Duration, jitter float64) { time.Sleep(AddJitter(baseDuration, jitter)) diff --git a/libpf/libpf.go b/libpf/libpf.go index 653d9ef5..64e51d13 100644 --- a/libpf/libpf.go +++ b/libpf/libpf.go @@ -5,8 +5,6 @@ package libpf // import "go.opentelemetry.io/ebpf-profiler/libpf" import ( "encoding/json" - "fmt" - "math" "time" ) @@ -32,36 +30,9 @@ func NowAsUInt32() uint32 { return uint32(time.Now().Unix()) } -// UnixTime64 represents nanoseconds or (reduced precision) seconds since epoch. +// UnixTime64 represents nanoseconds since epoch. type UnixTime64 uint64 -func (t UnixTime64) MarshalJSON() ([]byte, error) { - if t > math.MaxUint32 { - // Nanoseconds, ES does not support 'epoch_nanoseconds' so - // we have to pass it a value formatted as 'strict_date_optional_time_nanos'. - out := []byte(fmt.Sprintf("%q", - time.Unix(0, int64(t)).UTC().Format(time.RFC3339Nano))) - return out, nil - } - - // Reduced precision seconds-since-the-epoch, ES 'epoch_second' formatter will match these. - out := []byte(fmt.Sprintf("%d", t)) - return out, nil -} - -// Unix returns the value as seconds since epoch. -func (t UnixTime64) Unix() int64 { - if t > math.MaxUint32 { - // Nanoseconds, convert to seconds-since-the-epoch - return time.Unix(0, int64(t)).Unix() - } - - return int64(t) -} - -// Compile-time interface checks -var _ json.Marshaler = (*UnixTime64)(nil) - // AddressOrLineno represents a line number in an interpreted file or an offset into // a native file. type AddressOrLineno uint64 diff --git a/libpf/libpf_test.go b/libpf/libpf_test.go index d2f0e938..38dfea1e 100644 --- a/libpf/libpf_test.go +++ b/libpf/libpf_test.go @@ -4,12 +4,9 @@ package libpf import ( - "fmt" - "strconv" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestTraceType(t *testing.T) { @@ -45,35 +42,3 @@ func TestTraceType(t *testing.T) { assert.Equal(t, test.str, test.ty.String()) } } - -func TestUnixTime64_MarshalJSON(t *testing.T) { - tests := []struct { - name string - time UnixTime64 - want []byte - }{ - { - name: "zero", - time: UnixTime64(0), - want: []byte(strconv.Itoa(0)), - }, - { - name: "non-zero, seconds since the epoch", - time: UnixTime64(1710349106), - want: []byte(strconv.Itoa(1710349106)), - }, - { - name: "non-zero, nanoseconds since the epoch", - time: UnixTime64(1710349106864964685), - want: []byte(fmt.Sprintf("%q", "2024-03-13T16:58:26.864964685Z")), - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - b, err := test.time.MarshalJSON() - require.NoError(t, err) - assert.Equal(t, test.want, b) - }) - } -} diff --git a/libpf/pfelf/pfelf.go b/libpf/pfelf/pfelf.go index c3c66e08..a0dc8b67 100644 --- a/libpf/pfelf/pfelf.go +++ b/libpf/pfelf/pfelf.go @@ -20,24 +20,6 @@ import ( "go.opentelemetry.io/ebpf-profiler/libpf" ) -// SafeOpenELF opens the given ELF file in a safely way in that -// it recovers from panics inside elf.Open(). -// Under circumstances we see fatal errors from inside the runtime, which -// are not recoverable, e.g. "fatal error: runtime: out of memory". -func SafeOpenELF(name string) (elfFile *elf.File, err error) { - defer func() { - // debug/elf has issues with malformed ELF files - if r := recover(); r != nil { - if elfFile != nil { - elfFile.Close() - elfFile = nil - } - err = fmt.Errorf("failed to open ELF file (recovered from panic): %s", name) - } - }() - return elf.Open(name) -} - // HasDWARFData returns true if the provided ELF file contains actionable DWARF debugging // information. // This function does not call `elfFile.DWARF()` on purpose, as it can be extremely expensive in @@ -132,41 +114,6 @@ func GetDebugLink(elfFile *elf.File) (linkName string, crc32 int32, err error) { return ParseDebugLink(sectionData) } -// GetDebugAltLink returns the contents of the `.gnu_debugaltlink` section (path and build -// ID). If no link is present, ErrNoDebugLink is returned. -func GetDebugAltLink(elfFile *elf.File) (fileName, buildID string, err error) { - // The .gnu_debugaltlink section is not always present - sectionData, err := getSectionData(elfFile, ".gnu_debugaltlink") - if err != nil { - return "", "", ErrNoDebugLink - } - - // The whole .gnu_debugaltlink section consists of: - // 1) path to target (variable-length string) - // 2) null character separator (1 byte) - // 3) build ID (usually 20 bytes, but can vary) - // - // First, find the position of the null character: - nullCharIdx := bytes.IndexByte(sectionData, 0) - if nullCharIdx == -1 { - return "", "", nil - } - - // The path consists of all the characters before the first null character - path := strings.ToValidUTF8(string(sectionData[:nullCharIdx]), "") - - // Check that we can read a build ID: there should be at least 1 byte after the null character. - if nullCharIdx+1 == len(sectionData) { - return "", "", errors.New("malformed .gnu_debugaltlink section (missing build ID)") - } - - // The build ID consists of all the bytes after the first null character - buildIDBytes := sectionData[nullCharIdx+1:] - buildID = hex.EncodeToString(buildIDBytes) - - return path, buildID, nil -} - var ErrNoBuildID = errors.New("no build ID") var ubuntuKernelSignature = regexp.MustCompile(` \(Ubuntu[^)]*\)\n$`) @@ -303,32 +250,6 @@ func getNoteHexString(sectionBytes []byte, name string, noteType uint32) ( return hex.EncodeToString(sectionBytes[idxDataStart:idxDataEnd]), true, nil } -// GetLinuxBuildSalt extracts the linux kernel build salt from the provided ELF path. -// It is read from the .notes ELF section. -// It should be present in both kernel modules and the kernel image of most distro-vended kernel -// packages, and should be identical across all the files: kernel modules will have the same salt -// as their corresponding vmlinux image if they were built at the same time. -// This can be used to identify the kernel image corresponding to a module. -// See https://lkml.org/lkml/2018/7/3/1156 -func GetLinuxBuildSalt(filePath string) (salt string, found bool, err error) { - elfFile, err := SafeOpenELF(filePath) - if err != nil { - return "", false, fmt.Errorf("could not open %s: %w", filePath, err) - } - defer elfFile.Close() - - sectionData, err := getSectionData(elfFile, ".note.Linux") - if err != nil { - sectionData, err = getSectionData(elfFile, ".notes") - if err != nil { - return "", false, nil - } - } - - // 0x100 is defined as LINUX_ELFNOTE_BUILD_SALT in include/linux/build-salt.h - return getNoteHexString(sectionData, "Linux", 0x100) -} - func symbolMapFromELFSymbols(syms []elf.Symbol) *libpf.SymbolMap { symmap := &libpf.SymbolMap{} for _, sym := range syms { @@ -342,16 +263,6 @@ func symbolMapFromELFSymbols(syms []elf.Symbol) *libpf.SymbolMap { return symmap } -// GetSymbols gets the symbols of elf.File and returns them as libpf.SymbolMap for -// fast lookup by address and name. -func GetSymbols(elfFile *elf.File) (*libpf.SymbolMap, error) { - syms, err := elfFile.Symbols() - if err != nil { - return nil, err - } - return symbolMapFromELFSymbols(syms), nil -} - // GetDynamicSymbols gets the dynamic symbols of elf.File and returns them as libpf.SymbolMap for // fast lookup by address and name. func GetDynamicSymbols(elfFile *elf.File) (*libpf.SymbolMap, error) { @@ -362,43 +273,6 @@ func GetDynamicSymbols(elfFile *elf.File) (*libpf.SymbolMap, error) { return symbolMapFromELFSymbols(syms), nil } -// IsKernelModule returns true if the provided ELF file looks like a kernel module (an ELF with a -// .modinfo and .gnu.linkonce.this_module sections). -func IsKernelModule(file *elf.File) (bool, error) { - sectionFound, err := HasSection(file, ".modinfo") - if err != nil { - return false, err - } - - if !sectionFound { - return false, nil - } - - return HasSection(file, ".gnu.linkonce.this_module") -} - -// IsKernelImage returns true if the provided ELF file looks like a kernel image (an ELF with a -// __modver section). -func IsKernelImage(file *elf.File) (bool, error) { - return HasSection(file, "__modver") -} - -// IsKernelFile returns true if the provided ELF file looks like a kernel file (either a kernel -// image or a kernel module). -func IsKernelFile(file *elf.File) (bool, error) { - isModule, err := IsKernelImage(file) - if err != nil { - return false, err - } - - isImage, err := IsKernelModule(file) - if err != nil { - return false, err - } - - return isModule || isImage, nil -} - // IsGoBinary returns true if the provided file is a Go binary (= an ELF file with // a known Golang section). func IsGoBinary(file *elf.File) (bool, error) { diff --git a/libpf/readatbuf/readatbuf.go b/libpf/readatbuf/readatbuf.go index 0955e527..0596aaf7 100644 --- a/libpf/readatbuf/readatbuf.go +++ b/libpf/readatbuf/readatbuf.go @@ -111,6 +111,9 @@ func (reader *Reader) ReadAt(p []byte, off int64) (int, error) { if err != nil { return int(writeOffset), err } + if skipOffset > uint(len(data)) { + return 0, io.EOF + } copyLen := min(remaining, uint(len(data))-skipOffset) copy(p[writeOffset:][:copyLen], data[skipOffset:][:copyLen]) diff --git a/libpf/readatbuf/readatbuf_test.go b/libpf/readatbuf/readatbuf_test.go index b3d38e70..ac0d219f 100644 --- a/libpf/readatbuf/readatbuf_test.go +++ b/libpf/readatbuf/readatbuf_test.go @@ -5,6 +5,7 @@ package readatbuf_test import ( "bytes" + "io" "testing" "github.com/stretchr/testify/require" @@ -25,3 +26,18 @@ func TestCaching(t *testing.T) { testVariant(t, 1346, 11, 55) testVariant(t, 889, 34, 111) } + +func TestOutOfBoundsTail(t *testing.T) { + buf := bytes.NewReader([]byte{0, 1, 2, 3, 4, 5, 6, 7}) + r, err := readatbuf.New(buf, 5, 10) + require.NoError(t, err) + b := make([]byte, 1) + for i := int64(0); i < 32; i++ { + _, err = r.ReadAt(b, i) + if i > 7 { + require.ErrorIs(t, err, io.EOF) + } else { + require.NoError(t, err) + } + } +} diff --git a/libpf/tracehash.go b/libpf/tracehash.go index 71d1df22..be2bee3b 100644 --- a/libpf/tracehash.go +++ b/libpf/tracehash.go @@ -28,15 +28,6 @@ func TraceHashFromBytes(b []byte) (TraceHash, error) { return TraceHash{h}, nil } -// TraceHashFromString parses a byte slice of a trace hash into the internal data representation. -func TraceHashFromString(s string) (TraceHash, error) { - h, err := basehash.New128FromString(s) - if err != nil { - return TraceHash{}, err - } - return TraceHash{h}, nil -} - func (h TraceHash) Equal(other TraceHash) bool { return h.Hash128.Equal(other.Hash128) } diff --git a/main.go b/main.go index 7a5e0330..106413b8 100644 --- a/main.go +++ b/main.go @@ -124,7 +124,7 @@ func mainWithExitCode() exitCode { GRPCStartupBackoffTime: intervals.GRPCStartupBackoffTime(), GRPCConnectionTimeout: intervals.GRPCConnectionTimeout(), ReportInterval: intervals.ReportInterval(), - ExecutablesCacheElements: 4096, + ExecutablesCacheElements: 16384, // Next step: Calculate FramesCacheElements from numCores and samplingRate. FramesCacheElements: 65536, CGroupCacheElements: 1024, diff --git a/metrics/metrics.go b/metrics/metrics.go index 53a74ff9..58cd83b2 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -34,8 +34,23 @@ var ( //go:embed metrics.json metricsJSON []byte + + // Used in fallback checks, e.g. to avoid sending "counters" with 0 values + metricTypes map[MetricID]MetricType ) +func init() { + defs, err := GetDefinitions() + if err != nil { + panic("extracting definitions from metrics.json") + } + + metricTypes = make(map[MetricID]MetricType, len(defs)) + for _, md := range defs { + metricTypes[md.ID] = md.Type + } +} + // reporterImpl allows swapping out the global metrics reporter. // // nil is a valid value indicating that metrics should be voided. @@ -104,6 +119,10 @@ func AddSlice(newMetrics []Metric) { continue } + if metric.Value == 0 && metricTypes[metric.ID] == MetricTypeCounter { + continue + } + idx := metric.ID / 64 mask := uint64(1) << (metric.ID % 64) // Metric IDs 1-7 correspond to CPU/IO/Agent metrics and are scheduled diff --git a/metrics/metrics_test.go b/metrics/metrics_test.go index 38e2e549..664d19b1 100644 --- a/metrics/metrics_test.go +++ b/metrics/metrics_test.go @@ -41,6 +41,7 @@ func TestMetrics(t *testing.T) { {IDIOThroughput, MetricValue(55)}, {IDIODuration, MetricValue(66)}, {IDAgentGoRoutines, MetricValue(20)}, + {IDUnwindCallInterpreter, MetricValue(0)}, } AddSlice(inputMetrics[0:2]) // 33, 55 @@ -49,6 +50,10 @@ func TestMetrics(t *testing.T) { AddSlice(inputMetrics[3:4]) // 20 Add(inputMetrics[0].ID, inputMetrics[0].Value) // 33, dropped AddSlice(inputMetrics[1:3]) // 55, 66 dropped + AddSlice(inputMetrics[2:5]) // 66 dropped, 20 dropped, 0 dropped + + // Drop counter with 0 value as we don't expect it to appear in output + inputMetrics = inputMetrics[:4] // trigger reporting time.Sleep(1 * time.Second) diff --git a/proc/proc.go b/proc/proc.go index eeadeca6..4de6a249 100644 --- a/proc/proc.go +++ b/proc/proc.go @@ -121,10 +121,15 @@ func GetKernelModules(modulesPath string, count++ - nFields, _ := fmt.Sscanf(line, "%s %d %d %s %s 0x%x", + nFields, err := fmt.Sscanf(line, "%s %d %d %s %s 0x%x", &name, &size, &refcount, &dependencies, &state, &address) + if err != nil { + log.Warnf("error parsing line '%s' in modules: '%s'", line, err) + continue + } if nFields < 6 { - return nil, fmt.Errorf("unexpected line in modules: '%s'", line) + log.Warnf("unexpected line in modules: '%s'", line) + continue } if address == 0 { continue diff --git a/processmanager/ebpf/ebpf.go b/processmanager/ebpf/ebpf.go index 9f9dc90b..bb07da91 100644 --- a/processmanager/ebpf/ebpf.go +++ b/processmanager/ebpf/ebpf.go @@ -135,6 +135,8 @@ var outerMapsName = [...]string{ "exe_id_to_19_stack_deltas", "exe_id_to_20_stack_deltas", "exe_id_to_21_stack_deltas", + "exe_id_to_22_stack_deltas", + "exe_id_to_23_stack_deltas", } // Compile time check to make sure ebpfMapsImpl satisfies the interface . diff --git a/processmanager/ebpf/ebpf_test.go b/processmanager/ebpf/ebpf_test.go index d80a78fd..fec5bf5d 100644 --- a/processmanager/ebpf/ebpf_test.go +++ b/processmanager/ebpf/ebpf_test.go @@ -1,6 +1,3 @@ -//go:build !integration -// +build !integration - // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 @@ -12,6 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/ebpf-profiler/support" ) func TestMapID(t *testing.T) { @@ -26,6 +24,7 @@ func TestMapID(t *testing.T) { 0x3FF: 10, // 1023 0x400: 11, // 1024 0xFFFFF: 20, // 1048575 (2^20 - 1) + (1 << support.StackDeltaBucketLargest) - 1: support.StackDeltaBucketLargest, } for numStackDeltas, expectedShift := range testCases { numStackDeltas := numStackDeltas @@ -33,11 +32,11 @@ func TestMapID(t *testing.T) { t.Run(fmt.Sprintf("deltas %d", numStackDeltas), func(t *testing.T) { shift, err := getMapID(numStackDeltas) require.NoError(t, err) - assert.Equal(t, expectedShift, shift, - fmt.Sprintf("wrong map name for %d deltas", numStackDeltas)) + assert.Equal(t, expectedShift, shift, "wrong map name for %d deltas", + numStackDeltas) }) } - _, err := getMapID(1 << 22) + _, err := getMapID(1 << (support.StackDeltaBucketLargest + 1)) require.Error(t, err) } diff --git a/reporter/fifo.go b/reporter/fifo.go deleted file mode 100644 index e6c871b7..00000000 --- a/reporter/fifo.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package reporter // import "go.opentelemetry.io/ebpf-profiler/reporter" - -import ( - "fmt" - "sync" - - log "github.com/sirupsen/logrus" -) - -// FifoRingBuffer implements a first-in-first-out ring buffer that is safe for concurrent access. -type FifoRingBuffer[T any] struct { //nolint:gocritic - sync.Mutex - - // data holds the actual data. - data []T - - // emptyT is variable of type T used for nullifying entries in data[]. - emptyT T - - // name holds a string to uniquely identify the ring buffer in log messages. - name string - - // size is the maximum number of entries in the ring buffer. - size uint32 - - // readPos holds the position of the first element to be read in the data array. - readPos uint32 - - // writePos holds the position where the next element should be - // placed in the data array. - writePos uint32 - - // count holds a count of how many entries are in the array. - count uint32 - - // overwriteCount holds a count of the number of overwritten entries since the last metric - // report interval. - overwriteCount uint32 -} - -func (q *FifoRingBuffer[T]) InitFifo(size uint32, name string) error { - if size == 0 { - return fmt.Errorf("unsupported size of fifo: %d", size) - } - q.Lock() - defer q.Unlock() - q.size = size - q.data = make([]T, size) - q.readPos = 0 - q.writePos = 0 - q.count = 0 - q.overwriteCount = 0 - q.name = name - return nil -} - -// zeroFifo re-initializes the ring buffer and clears the data array, making previously -// stored elements available for GC. -func (q *FifoRingBuffer[T]) zeroFifo() { - if err := q.InitFifo(q.size, q.name); err != nil { - // Should never happen - panic(err) - } -} - -// Append adds element v to the FifoRingBuffer. it overwrites existing elements if there is no -// space left. -func (q *FifoRingBuffer[T]) Append(v T) { - q.Lock() - defer q.Unlock() - - q.data[q.writePos] = v - q.writePos++ - - if q.writePos == q.size { - q.writePos = 0 - } - - if q.count < q.size { - q.count++ - if q.count == q.size { - log.Warnf("About to start overwriting elements in buffer for %s", - q.name) - } - } else { - q.overwriteCount++ - q.readPos = q.writePos - } -} - -// ReadAll returns all elements from the FifoRingBuffer. -func (q *FifoRingBuffer[T]) ReadAll() []T { - q.Lock() - defer q.Unlock() - - data := make([]T, q.count) - readPos := q.readPos - - for i := uint32(0); i < q.count; i++ { - pos := (i + readPos) % q.size - data[i] = q.data[pos] - // Allow for element to be GCed - q.data[pos] = q.emptyT - } - - q.readPos = q.writePos - q.count = 0 - - return data -} - -func (q *FifoRingBuffer[T]) GetOverwriteCount() uint32 { - q.Lock() - defer q.Unlock() - - count := q.overwriteCount - q.overwriteCount = 0 - return count -} diff --git a/reporter/fifo_test.go b/reporter/fifo_test.go deleted file mode 100644 index 7a4c7a80..00000000 --- a/reporter/fifo_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package reporter - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestFifo(t *testing.T) { - var integers []int - integers = append(integers, 1, 2, 3, 4, 5) - - var integersShared []int - integersShared = append(integersShared, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) - - var retIntegers []int - retIntegers = append(retIntegers, 3, 4, 5) - - var retIntegersShared []int - retIntegersShared = append(retIntegersShared, 8, 9, 10, 11, 12) - - sharedFifo := &FifoRingBuffer[int]{} - err := sharedFifo.InitFifo(5, t.Name()) - require.NoError(t, err) - - //nolint:lll - tests := map[string]struct { - // size defines the size of the fifo. - size uint32 - // data will be written to and extracted from the fifo. - data []int - // returned reflects the data that is expected from the fifo - // after writing to it. - returned []int - // the number of overwrites that occurred - overwriteCount uint32 - // err indicates if an error is expected for this testcase. - err bool - // sharedFifo indicates if a shared fifo should be used. - // If false, a new fifo is used, specific to the testcase. - sharedFifo bool - // parallel indicates if parallelism should be enabled for this testcase. - parallel bool - }{ - // This testcase simulates a fifo with an invalid size of 0. - "Invalid size": {size: 0, err: true, parallel: true}, - // This testcase simulates a case where the numbers of elements - // written to the fifo represents the size of the fifo. - "Full Fifo": {size: 5, data: integers, returned: integers, overwriteCount: 0, parallel: true}, - // This testcase simulates a case where the number of elements - // written to the fifo exceed the size of the fifo. - "Fifo overflow": {size: 3, data: integers, returned: retIntegers, overwriteCount: 2, parallel: true}, - // This testcase simulates a case where only a few elements are - // written to the fifo and don't exceed the size of the fifo. - "Partial full": {size: 15, data: integers, returned: integers, overwriteCount: 0, parallel: true}, - - // The following test cases share the same fifo - - // This testcase simulates a case where the numbers of elements - // written to the fifo represents the size of the fifo. - "Shared Full Fifo": {data: integers, returned: integers, overwriteCount: 0, sharedFifo: true}, - // This testcase simulates a case where the number of elements - // written to the fifo exceed the size of the fifo. - "Shared Fifo overflow": {data: integersShared, returned: retIntegersShared, overwriteCount: 7, sharedFifo: true}, - } - - for name, testcase := range tests { - name := name - testcase := testcase - var fifo *FifoRingBuffer[int] - - t.Run(name, func(t *testing.T) { - if testcase.parallel { - t.Parallel() - } - - if testcase.sharedFifo { - fifo = sharedFifo - } else { - fifo = &FifoRingBuffer[int]{} - err := fifo.InitFifo(testcase.size, t.Name()) - if testcase.err { - require.Error(t, err) - return - } - require.NoError(t, err) - } - - empty := fifo.ReadAll() - require.Empty(t, empty) - - for _, v := range testcase.data { - fifo.Append(v) - } - - data := fifo.ReadAll() - for i := uint32(0); i < fifo.size; i++ { - assert.Equalf(t, 0, fifo.data[i], "fifo not empty after ReadAll(), idx: %d", i) - } - assert.Equal(t, testcase.returned, data) - assert.Equal(t, testcase.overwriteCount, fifo.GetOverwriteCount(), "overwrite count") - assert.Zero(t, fifo.GetOverwriteCount(), "overwrite count not reset") - }) - } -} - -func TestFifo_isWritableWhenZeroed(t *testing.T) { - fifo := &FifoRingBuffer[int]{} - require.NoError(t, fifo.InitFifo(1, t.Name())) - fifo.zeroFifo() - assert.NotPanics(t, func() { - fifo.Append(123) - }) -} diff --git a/reporter/iface.go b/reporter/iface.go index 85e4a1b2..7cf19cf3 100644 --- a/reporter/iface.go +++ b/reporter/iface.go @@ -36,6 +36,7 @@ type TraceEventMeta struct { Comm string APMServiceName string PID, TID libpf.PID + CPU int } type TraceReporter interface { diff --git a/reporter/otlp_reporter.go b/reporter/otlp_reporter.go index 35d6b056..c2fbdf29 100644 --- a/reporter/otlp_reporter.go +++ b/reporter/otlp_reporter.go @@ -4,14 +4,10 @@ package reporter // import "go.opentelemetry.io/ebpf-profiler/reporter" import ( - "bufio" "context" "crypto/rand" "crypto/tls" - "fmt" "maps" - "os" - "regexp" "slices" "strconv" "time" @@ -33,8 +29,8 @@ import ( "go.opentelemetry.io/ebpf-profiler/libpf/xsync" ) -var ( - cgroupv2PathPattern = regexp.MustCompile(`0:.*?:(.*)`) +const ( + executableCacheLifetime = 1 * time.Hour ) // Assert that we implement the full Reporter interface. @@ -70,6 +66,7 @@ type traceAndMetaKey struct { apmServiceName string // containerID is annotated based on PID information containerID string + pid int64 } // traceEvents holds known information about a trace. @@ -84,9 +81,11 @@ type traceEvents struct { } // attrKeyValue is a helper to populate Profile.attribute_table. -type attrKeyValue struct { - key string - value string +type attrKeyValue[T string | int64] struct { + key string + // Set to true for OTel SemConv attributes with requirement level: Required + required bool + value T } // OTLPReporter receives and transforms information to be OTLP/profiles compliant. @@ -101,8 +100,8 @@ type OTLPReporter struct { // client for the connection to the receiver. client otlpcollector.ProfilesServiceClient - // stopSignal is the stop signal for shutting down all background tasks. - stopSignal chan libpf.Void + // runLoop handles the run loop + runLoop *runLoop // rpcStats stores gRPC related statistics. rpcStats *StatsHandlerImpl @@ -152,7 +151,7 @@ func NewOTLP(cfg *Config) (*OTLPReporter, error) { if err != nil { return nil, err } - executables.SetLifetime(1 * time.Hour) // Allow GC to clean stale items. + executables.SetLifetime(executableCacheLifetime) // Allow GC to clean stale items. frames, err := lru.NewSynced[libpf.FileID, *xsync.RWMutex[map[libpf.AddressOrLineno]sourceInfo]]( @@ -179,15 +178,17 @@ func NewOTLP(cfg *Config) (*OTLPReporter, error) { } return &OTLPReporter{ - config: cfg, - name: cfg.Name, - version: cfg.Version, - kernelVersion: cfg.KernelVersion, - hostName: cfg.HostName, - ipAddress: cfg.IPAddress, - samplesPerSecond: cfg.SamplesPerSecond, - hostID: strconv.FormatUint(cfg.HostID, 10), - stopSignal: make(chan libpf.Void), + config: cfg, + name: cfg.Name, + version: cfg.Version, + kernelVersion: cfg.KernelVersion, + hostName: cfg.HostName, + ipAddress: cfg.IPAddress, + samplesPerSecond: cfg.SamplesPerSecond, + hostID: strconv.FormatUint(cfg.HostID, 10), + runLoop: &runLoop{ + stopSignal: make(chan libpf.Void), + }, pkgGRPCOperationTimeout: cfg.GRPCOperationTimeout, client: nil, rpcStats: NewStatsHandler(), @@ -213,7 +214,7 @@ func (r *OTLPReporter) ReportTraceEvent(trace *libpf.Trace, meta *TraceEventMeta traceEventsMap := r.traceEvents.WLock() defer r.traceEvents.WUnlock(&traceEventsMap) - containerID, err := r.lookupCgroupv2(meta.PID) + containerID, err := libpf.LookupCgroupv2(r.cgroupv2ID, meta.PID) if err != nil { log.Debugf("Failed to get a cgroupv2 ID as container ID for PID %d: %v", meta.PID, err) @@ -224,6 +225,7 @@ func (r *OTLPReporter) ReportTraceEvent(trace *libpf.Trace, meta *TraceEventMeta comm: meta.Comm, apmServiceName: meta.APMServiceName, containerID: containerID, + pid: int64(meta.PID), } if events, exists := (*traceEventsMap)[key]; exists { @@ -344,7 +346,7 @@ func (r *OTLPReporter) ReportMetrics(_ uint32, _ []uint32, _ []int64) {} // Stop triggers a graceful shutdown of OTLPReporter. func (r *OTLPReporter) Stop() { - close(r.stopSignal) + r.runLoop.Stop() } // GetMetrics returns internal metrics of OTLPReporter. @@ -368,41 +370,27 @@ func (r *OTLPReporter) Start(ctx context.Context) error { otlpGrpcConn, err := waitGrpcEndpoint(ctx, r.config, r.rpcStats) if err != nil { cancelReporting() - close(r.stopSignal) + r.runLoop.Stop() return err } r.client = otlpcollector.NewProfilesServiceClient(otlpGrpcConn) - go func() { - tick := time.NewTicker(r.config.ReportInterval) - defer tick.Stop() - purgeTick := time.NewTicker(5 * time.Minute) - defer purgeTick.Stop() - for { - select { - case <-ctx.Done(): - return - case <-r.stopSignal: - return - case <-tick.C: - if err := r.reportOTLPProfile(ctx); err != nil { - log.Errorf("Request failed: %v", err) - } - tick.Reset(libpf.AddJitter(r.config.ReportInterval, 0.2)) - case <-purgeTick.C: - // Allow the GC to purge expired entries to avoid memory leaks. - r.executables.PurgeExpired() - r.frames.PurgeExpired() - r.cgroupv2ID.PurgeExpired() - } + r.runLoop.Start(ctx, r.config.ReportInterval, func() { + if err := r.reportOTLPProfile(ctx); err != nil { + log.Errorf("Request failed: %v", err) } - }() + }, func() { + // Allow the GC to purge expired entries to avoid memory leaks. + r.executables.PurgeExpired() + r.frames.PurgeExpired() + r.cgroupv2ID.PurgeExpired() + }) // When Stop() is called and a signal to 'stop' is received, then: // - cancel the reporting functions currently running (using context) // - close the gRPC connection with collection-agent go func() { - <-r.stopSignal + <-r.runLoop.stopSignal cancelReporting() if err := otlpGrpcConn.Close(); err != nil { log.Fatalf("Stopping connection of OTLP client client failed: %v", err) @@ -566,7 +554,7 @@ func (r *OTLPReporter) getProfile() (profile *profiles.Profile, startTS, endTS u // Walk every frame of the trace. for i := range traceInfo.frameTypes { - frameAttributes := addProfileAttributes(profile, []attrKeyValue{ + frameAttributes := addProfileAttributes(profile, []attrKeyValue[string]{ {key: "profile.frame.type", value: traceInfo.frameTypes[i].String()}, }, attributeMap) @@ -590,7 +578,9 @@ func (r *OTLPReporter) getProfile() (profile *profiles.Profile, startTS, endTS u fileIDtoMapping[traceInfo.files[i]] = idx locationMappingIndex = idx - execInfo, exists := r.executables.Get(traceInfo.files[i]) + // Ensure that actively used executables do not expire. + execInfo, exists := r.executables.GetAndRefresh(traceInfo.files[i], + executableCacheLifetime) // Next step: Select a proper default value, // if the name of the executable is not known yet. @@ -599,12 +589,12 @@ func (r *OTLPReporter) getProfile() (profile *profiles.Profile, startTS, endTS u fileName = execInfo.fileName } - mappingAttributes := addProfileAttributes(profile, []attrKeyValue{ + mappingAttributes := addProfileAttributes(profile, []attrKeyValue[string]{ // Once SemConv and its Go package is released with the new // semantic convention for build_id, replace these hard coded // strings. {key: "process.executable.build_id.gnu", value: execInfo.gnuBuildID}, - {key: "process.executable.build_id.profiling", + {key: "process.executable.build_id.htlhash", value: traceInfo.files[i].StringNoQuotes()}, }, attributeMap) @@ -658,17 +648,19 @@ func (r *OTLPReporter) getProfile() (profile *profiles.Profile, startTS, endTS u loc.Line = append(loc.Line, line) // To be compliant with the protocol, generate a dummy mapping entry. - loc.MappingIndex = getDummyMappingIndex(fileIDtoMapping, stringMap, - profile, traceInfo.files[i]) + loc.MappingIndex = getDummyMappingIndex(fileIDtoMapping, + stringMap, attributeMap, profile, traceInfo.files[i]) } profile.Location = append(profile.Location, loc) } - sample.Attributes = addProfileAttributes(profile, []attrKeyValue{ + sample.Attributes = append(addProfileAttributes(profile, []attrKeyValue[string]{ {key: string(semconv.ContainerIDKey), value: traceKey.containerID}, {key: string(semconv.ThreadNameKey), value: traceKey.comm}, {key: string(semconv.ServiceNameKey), value: traceKey.apmServiceName}, - }, attributeMap) + }, attributeMap), addProfileAttributes(profile, []attrKeyValue[int64]{ + {key: string(semconv.ProcessPIDKey), value: traceKey.pid}, + }, attributeMap)...) sample.LocationsLength = uint64(len(traceInfo.frameTypes)) locationIndex += sample.LocationsLength @@ -739,15 +731,29 @@ func createFunctionEntry(funcMap map[funcInfo]uint64, // addProfileAttributes adds attributes to Profile.attribute_table and returns // the indices to these attributes. -func addProfileAttributes(profile *profiles.Profile, - attributes []attrKeyValue, attributeMap map[string]uint64) []uint64 { +func addProfileAttributes[T string | int64](profile *profiles.Profile, + attributes []attrKeyValue[T], attributeMap map[string]uint64) []uint64 { indices := make([]uint64, 0, len(attributes)) - addAttr := func(attr attrKeyValue) { - if attr.value == "" { + addAttr := func(attr attrKeyValue[T]) { + var attributeCompositeKey string + var attributeValue common.AnyValue + + switch val := any(attr.value).(type) { + case string: + if !attr.required && val == "" { + return + } + attributeCompositeKey = attr.key + "_" + val + attributeValue = common.AnyValue{Value: &common.AnyValue_StringValue{StringValue: val}} + case int64: + attributeCompositeKey = attr.key + "_" + strconv.Itoa(int(val)) + attributeValue = common.AnyValue{Value: &common.AnyValue_IntValue{IntValue: val}} + default: + log.Error("Unsupported attribute value type. Only string and int64 are supported.") return } - attributeCompositeKey := attr.key + "_" + attr.value + if attributeIndex, exists := attributeMap[attributeCompositeKey]; exists { indices = append(indices, attributeIndex) return @@ -756,7 +762,7 @@ func addProfileAttributes(profile *profiles.Profile, indices = append(indices, newIndex) profile.AttributeTable = append(profile.AttributeTable, &common.KeyValue{ Key: attr.key, - Value: &common.AnyValue{Value: &common.AnyValue_StringValue{StringValue: attr.value}}, + Value: &attributeValue, }) attributeMap[attributeCompositeKey] = newIndex } @@ -770,24 +776,23 @@ func addProfileAttributes(profile *profiles.Profile, // getDummyMappingIndex inserts or looks up an entry for interpreted FileIDs. func getDummyMappingIndex(fileIDtoMapping map[libpf.FileID]uint64, - stringMap map[string]uint32, profile *profiles.Profile, - fileID libpf.FileID) uint64 { - var locationMappingIndex uint64 + stringMap map[string]uint32, attributeMap map[string]uint64, + profile *profiles.Profile, fileID libpf.FileID) uint64 { if tmpMappingIndex, exists := fileIDtoMapping[fileID]; exists { - locationMappingIndex = tmpMappingIndex - } else { - idx := uint64(len(fileIDtoMapping)) - fileIDtoMapping[fileID] = idx - locationMappingIndex = idx - - profile.Mapping = append(profile.Mapping, &profiles.Mapping{ - Filename: int64(getStringMapIndex(stringMap, "")), - BuildId: int64(getStringMapIndex(stringMap, - fileID.StringNoQuotes())), - BuildIdKind: *profiles.BuildIdKind_BUILD_ID_BINARY_HASH.Enum(), - }) + return tmpMappingIndex } - return locationMappingIndex + idx := uint64(len(fileIDtoMapping)) + fileIDtoMapping[fileID] = idx + + mappingAttributes := addProfileAttributes(profile, []attrKeyValue[string]{ + {key: "process.executable.build_id.htlhash", + value: fileID.StringNoQuotes()}}, attributeMap) + + profile.Mapping = append(profile.Mapping, &profiles.Mapping{ + Filename: int64(getStringMapIndex(stringMap, "")), + Attributes: mappingAttributes, + }) + return idx } // waitGrpcEndpoint waits until the gRPC connection is established. @@ -852,44 +857,3 @@ func setupGrpcConnection(parent context.Context, cfg *Config, //nolint:staticcheck return grpc.DialContext(ctx, cfg.CollAgentAddr, opts...) } - -// lookupCgroupv2 returns the cgroupv2 ID for pid. -func (r *OTLPReporter) lookupCgroupv2(pid libpf.PID) (string, error) { - id, ok := r.cgroupv2ID.Get(pid) - if ok { - return id, nil - } - - // Slow path - f, err := os.Open(fmt.Sprintf("/proc/%d/cgroup", pid)) - if err != nil { - return "", err - } - defer f.Close() - - var genericCgroupv2 string - scanner := bufio.NewScanner(f) - buf := make([]byte, 512) - // Providing a predefined buffer overrides the internal buffer that Scanner uses (4096 bytes). - // We can do that and also set a maximum allocation size on the following call. - // With a maximum of 4096 characters path in the kernel, 8192 should be fine here. We don't - // expect lines in /proc//cgroup to be longer than that. - scanner.Buffer(buf, 8192) - var pathParts []string - for scanner.Scan() { - line := scanner.Text() - pathParts = cgroupv2PathPattern.FindStringSubmatch(line) - if pathParts == nil { - log.Debugf("Could not extract cgroupv2 path from line: %s", line) - continue - } - genericCgroupv2 = pathParts[1] - break - } - - // Cache the cgroupv2 information. - // To avoid busy lookups, also empty cgroupv2 information is cached. - r.cgroupv2ID.Add(pid, genericCgroupv2) - - return genericCgroupv2, nil -} diff --git a/reporter/otlp_reporter_test.go b/reporter/otlp_reporter_test.go index d9c2844f..42c64d04 100644 --- a/reporter/otlp_reporter_test.go +++ b/reporter/otlp_reporter_test.go @@ -26,11 +26,19 @@ func TestGetSampleAttributes(t *testing.T) { comm: "", apmServiceName: "", containerID: "", + pid: 0, + }, + }, + attributeMap: make(map[string]uint64), + expectedIndices: [][]uint64{{0}}, + expectedAttributeTable: []*common.KeyValue{ + { + Key: "process.pid", + Value: &common.AnyValue{ + Value: &common.AnyValue_IntValue{IntValue: 0}, + }, }, }, - attributeMap: make(map[string]uint64), - expectedIndices: [][]uint64{make([]uint64, 0, 4)}, - expectedAttributeTable: nil, }, "duplicate": { profile: &profiles.Profile{}, @@ -40,16 +48,18 @@ func TestGetSampleAttributes(t *testing.T) { comm: "comm1", apmServiceName: "apmServiceName1", containerID: "containerID1", + pid: 1234, }, { hash: libpf.TraceHash{}, comm: "comm1", apmServiceName: "apmServiceName1", containerID: "containerID1", + pid: 1234, }, }, attributeMap: make(map[string]uint64), - expectedIndices: [][]uint64{{0, 1, 2}, {0, 1, 2}}, + expectedIndices: [][]uint64{{0, 1, 2, 3}, {0, 1, 2, 3}}, expectedAttributeTable: []*common.KeyValue{ { Key: "container.id", @@ -69,6 +79,12 @@ func TestGetSampleAttributes(t *testing.T) { Value: &common.AnyValue_StringValue{StringValue: "apmServiceName1"}, }, }, + { + Key: "process.pid", + Value: &common.AnyValue{ + Value: &common.AnyValue_IntValue{IntValue: 1234}, + }, + }, }, }, "different": { @@ -79,16 +95,18 @@ func TestGetSampleAttributes(t *testing.T) { comm: "comm1", apmServiceName: "apmServiceName1", containerID: "containerID1", + pid: 1234, }, { hash: libpf.TraceHash{}, comm: "comm2", apmServiceName: "apmServiceName2", containerID: "containerID2", + pid: 6789, }, }, attributeMap: make(map[string]uint64), - expectedIndices: [][]uint64{{0, 1, 2}, {3, 4, 5}}, + expectedIndices: [][]uint64{{0, 1, 2, 3}, {4, 5, 6, 7}}, expectedAttributeTable: []*common.KeyValue{ { Key: "container.id", @@ -108,6 +126,12 @@ func TestGetSampleAttributes(t *testing.T) { Value: &common.AnyValue_StringValue{StringValue: "apmServiceName1"}, }, }, + { + Key: "process.pid", + Value: &common.AnyValue{ + Value: &common.AnyValue_IntValue{IntValue: 1234}, + }, + }, { Key: "container.id", Value: &common.AnyValue{ @@ -126,6 +150,12 @@ func TestGetSampleAttributes(t *testing.T) { Value: &common.AnyValue_StringValue{StringValue: "apmServiceName2"}, }, }, + { + Key: "process.pid", + Value: &common.AnyValue{ + Value: &common.AnyValue_IntValue{IntValue: 6789}, + }, + }, }, }, } @@ -136,11 +166,16 @@ func TestGetSampleAttributes(t *testing.T) { t.Run(name, func(t *testing.T) { indices := make([][]uint64, 0) for _, k := range tc.k { - indices = append(indices, addProfileAttributes(tc.profile, []attrKeyValue{ - {key: string(semconv.ContainerIDKey), value: k.containerID}, - {key: string(semconv.ThreadNameKey), value: k.comm}, - {key: string(semconv.ServiceNameKey), value: k.apmServiceName}, - }, tc.attributeMap)) + indices = append(indices, append(addProfileAttributes(tc.profile, + []attrKeyValue[string]{ + {key: string(semconv.ContainerIDKey), value: k.containerID}, + {key: string(semconv.ThreadNameKey), value: k.comm}, + {key: string(semconv.ServiceNameKey), value: k.apmServiceName}, + }, tc.attributeMap), + addProfileAttributes(tc.profile, + []attrKeyValue[int64]{ + {key: string(semconv.ProcessPIDKey), value: k.pid}, + }, tc.attributeMap)...)) } require.Equal(t, tc.expectedIndices, indices) require.Equal(t, tc.expectedAttributeTable, tc.profile.AttributeTable) diff --git a/reporter/runloop.go b/reporter/runloop.go new file mode 100644 index 00000000..0014d634 --- /dev/null +++ b/reporter/runloop.go @@ -0,0 +1,44 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package reporter // import "go.opentelemetry.io/ebpf-profiler/reporter" + +import ( + "context" + "time" + + "go.opentelemetry.io/ebpf-profiler/libpf" +) + +// runLoop implements the run loop for all reporters +type runLoop struct { + // stopSignal is the stop signal for shutting down all background tasks. + stopSignal chan libpf.Void +} + +func (rl *runLoop) Start(ctx context.Context, reportInterval time.Duration, run, purge func()) { + go func() { + tick := time.NewTicker(reportInterval) + defer tick.Stop() + purgeTick := time.NewTicker(5 * time.Minute) + defer purgeTick.Stop() + + for { + select { + case <-ctx.Done(): + return + case <-rl.stopSignal: + return + case <-tick.C: + run() + tick.Reset(libpf.AddJitter(reportInterval, 0.2)) + case <-purgeTick.C: + purge() + } + } + }() +} + +func (rl *runLoop) Stop() { + close(rl.stopSignal) +} diff --git a/stringutil/stringutil.go b/stringutil/stringutil.go index 3d8b4a88..06a19988 100644 --- a/stringutil/stringutil.go +++ b/stringutil/stringutil.go @@ -84,8 +84,3 @@ func SplitN(s, sep string, f []string) int { func ByteSlice2String(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } - -// StrDataPtr returns the string's underlying Data pointer through reflection. -func StrDataPtr(s string) *byte { - return unsafe.StringData(s) -} diff --git a/support/ebpf/dotnet_tracer.ebpf.c b/support/ebpf/dotnet_tracer.ebpf.c index c36dd294..7ebac864 100644 --- a/support/ebpf/dotnet_tracer.ebpf.c +++ b/support/ebpf/dotnet_tracer.ebpf.c @@ -170,7 +170,7 @@ ErrorCode unwind_one_dotnet_frame(PerCPURecord *record, DotnetProcInfo *vi, bool u64 code_start = state->text_section_bias; u64 code_header_ptr = pc; - state->return_address = true; + unwinder_mark_nonleaf_frame(state); if (type < 0x100 && (type & DOTNET_CODE_FLAG_LEAF)) { // Stub frame that does not do calls. diff --git a/support/ebpf/extmaps.h b/support/ebpf/extmaps.h index 76a83f57..5922d9ed 100644 --- a/support/ebpf/extmaps.h +++ b/support/ebpf/extmaps.h @@ -38,6 +38,8 @@ extern bpf_map_def exe_id_to_18_stack_deltas; extern bpf_map_def exe_id_to_19_stack_deltas; extern bpf_map_def exe_id_to_20_stack_deltas; extern bpf_map_def exe_id_to_21_stack_deltas; +extern bpf_map_def exe_id_to_22_stack_deltas; +extern bpf_map_def exe_id_to_23_stack_deltas; extern bpf_map_def hotspot_procs; extern bpf_map_def kernel_stackmap; extern bpf_map_def dotnet_procs; diff --git a/support/ebpf/hotspot_tracer.ebpf.c b/support/ebpf/hotspot_tracer.ebpf.c index c63f14d6..9ae1fdc7 100644 --- a/support/ebpf/hotspot_tracer.ebpf.c +++ b/support/ebpf/hotspot_tracer.ebpf.c @@ -719,7 +719,7 @@ ErrorCode hotspot_execute_unwind_action(CodeBlobInfo *cbi, HotspotUnwindAction a return ERR_UNREACHABLE; #if defined(__aarch64__) case UA_UNWIND_AARCH64_LR: - if (state->return_address) { + if (state->lr_invalid) { increment_metric(metricID_UnwindHotspotErrLrUnwindingMidTrace); return ERR_HOTSPOT_LR_UNWINDING_MID_TRACE; } @@ -761,7 +761,7 @@ ErrorCode hotspot_execute_unwind_action(CodeBlobInfo *cbi, HotspotUnwindAction a state->pc = ui->pc; state->sp = ui->sp; state->fp = ui->fp; - state->return_address = true; + unwinder_mark_nonleaf_frame(state); increment_metric(metricID_UnwindHotspotFrames); } } diff --git a/support/ebpf/native_stack_trace.ebpf.c b/support/ebpf/native_stack_trace.ebpf.c index d9c56f3b..959099cb 100644 --- a/support/ebpf/native_stack_trace.ebpf.c +++ b/support/ebpf/native_stack_trace.ebpf.c @@ -37,6 +37,8 @@ STACK_DELTA_BUCKET(18); STACK_DELTA_BUCKET(19); STACK_DELTA_BUCKET(20); STACK_DELTA_BUCKET(21); +STACK_DELTA_BUCKET(22); +STACK_DELTA_BUCKET(23); // Unwind info value for invalid stack delta #define STACK_DELTA_INVALID (STACK_DELTA_COMMAND_FLAG | UNWIND_COMMAND_INVALID) @@ -154,6 +156,8 @@ void *get_stack_delta_map(int mapID) { case 19: return &exe_id_to_19_stack_deltas; case 20: return &exe_id_to_20_stack_deltas; case 21: return &exe_id_to_21_stack_deltas; + case 22: return &exe_id_to_22_stack_deltas; + case 23: return &exe_id_to_23_stack_deltas; default: return NULL; } } @@ -472,7 +476,7 @@ static ErrorCode unwind_one_frame(u64 pid, u32 frame_idx, UnwindState *state, bo return ERR_NATIVE_PC_READ; } state->sp = cfa; - state->return_address = true; + unwinder_mark_nonleaf_frame(state); frame_ok: increment_metric(metricID_UnwindNativeFrames); return ERR_OK; @@ -512,6 +516,7 @@ static ErrorCode unwind_one_frame(u64 pid, u32 frame_idx, struct UnwindState *st state->lr = normalize_pac_ptr(rt_regs[30]); state->r22 = rt_regs[22]; state->return_address = false; + state->lr_invalid = false; DEBUG_PRINT("signal frame"); goto frame_ok; case UNWIND_COMMAND_STOP: @@ -548,7 +553,7 @@ static ErrorCode unwind_one_frame(u64 pid, u32 frame_idx, struct UnwindState *st if (info->fpOpcode == UNWIND_OPCODE_BASE_LR) { // Allow LR unwinding only if it's known to be valid: either because // it's the topmost user-mode frame, or recovered by signal trampoline. - if (state->return_address) { + if (state->lr_invalid) { increment_metric(metricID_UnwindNativeErrLrUnwindingMidTrace); return ERR_NATIVE_LR_UNWINDING_MID_TRACE; } @@ -593,7 +598,7 @@ static ErrorCode unwind_one_frame(u64 pid, u32 frame_idx, struct UnwindState *st } state->sp = cfa; - state->return_address = true; + unwinder_mark_nonleaf_frame(state); frame_ok: increment_metric(metricID_UnwindNativeFrames); return ERR_OK; @@ -642,7 +647,12 @@ static inline ErrorCode copy_state_regs(UnwindState *state, // Treat syscalls as return addresses, but not IRQ handling, page faults, etc.. // https://github.com/torvalds/linux/blob/2ef5971ff3/arch/arm64/include/asm/ptrace.h#L118 // https://github.com/torvalds/linux/blob/2ef5971ff3/arch/arm64/include/asm/ptrace.h#L206-L209 + // + // Note: We do not use `unwinder_mark_nonleaf_frame` here, + // because the frame is a leaf frame from the perspective of the user stack, + // regardless of whether we are in a syscall. state->return_address = interrupted_kernelmode && regs->syscallno != -1; + state->lr_invalid = false; #endif return ERR_OK; diff --git a/support/ebpf/tracemgmt.h b/support/ebpf/tracemgmt.h index d2c58d53..c0e08a45 100644 --- a/support/ebpf/tracemgmt.h +++ b/support/ebpf/tracemgmt.h @@ -200,6 +200,7 @@ static inline PerCPURecord *get_pristine_per_cpu_record() #elif defined(__aarch64__) record->state.lr = 0; record->state.r22 = 0; + record->state.lr_invalid = false; #endif record->state.return_address = false; record->state.error_metric = -1; @@ -242,6 +243,25 @@ void unwinder_mark_done(PerCPURecord *record, int unwinder) { record->unwindersDone |= 1U << unwinder; } +// unwinder_mark_nonleaf_frame marks the current frame as a non-leaf +// frame from the perspective of the user-mode stack. +// That is, frames that are making a syscall (thus the leaf for the user-mode +// stack, though not the leaf for the entire logical stack) *are* +// considered leaf frames in this sense. +// +// On both x86 and aarch64, this means we need to subtract 1 from +// the address during later processing. +// +// Additionally, on aarch64, this means that we will not trust the current value of +// `lr` to be the return address for this frame. +static inline __attribute__((__always_inline__)) +void unwinder_mark_nonleaf_frame(UnwindState *state) { + state->return_address = true; +#if defined(__aarch64__) + state->lr_invalid = true; +#endif +} + // Push the file ID, line number and frame type into FrameList with a user-defined // maximum stack size. // diff --git a/support/ebpf/tracer.ebpf.release.amd64 b/support/ebpf/tracer.ebpf.release.amd64 index 9ff3eabbddde8008f5a5035270ed32adf489caac..2a8cbb2fd2bc85674a9b2d3c2c6223fb9f4f06b1 100644 GIT binary patch delta 48904 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 H=WG8D(zgaC delta 48028 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 JuE~}A{{iTtH!}bL diff --git a/support/ebpf/tracer.ebpf.release.arm64 b/support/ebpf/tracer.ebpf.release.arm64 index dca6175efa4bfbd3b607d3ae65e11b9102373b59..ecac9895a53d1f5bcafec570197a20e0625dade4 100644 GIT binary patch literal 291032 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 literal 289904 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 = fp + sizeof(regs); state->fp = regs[0]; state->pc = regs[1]; - state->return_address = true; + unwinder_mark_nonleaf_frame(state); DEBUG_PRINT("v8: pc: %lx, sp: %lx, fp: %lx", (unsigned long) state->pc, (unsigned long) state->sp, diff --git a/tools/coredump/ebpfhelpers.go b/tools/coredump/ebpfhelpers.go index 3f3ef07a..f4088917 100644 --- a/tools/coredump/ebpfhelpers.go +++ b/tools/coredump/ebpfhelpers.go @@ -114,7 +114,8 @@ func __bpf_map_lookup_elem(id C.u64, mapdef *C.bpf_map_def, keyptr unsafe.Pointe &C.exe_id_to_11_stack_deltas, &C.exe_id_to_12_stack_deltas, &C.exe_id_to_13_stack_deltas, &C.exe_id_to_14_stack_deltas, &C.exe_id_to_15_stack_deltas, &C.exe_id_to_16_stack_deltas, &C.exe_id_to_17_stack_deltas, &C.exe_id_to_18_stack_deltas, &C.exe_id_to_19_stack_deltas, - &C.exe_id_to_20_stack_deltas, &C.exe_id_to_21_stack_deltas: + &C.exe_id_to_20_stack_deltas, &C.exe_id_to_21_stack_deltas, &C.exe_id_to_22_stack_deltas, + &C.exe_id_to_23_stack_deltas: ctx.stackDeltaFileID = *(*C.u64)(keyptr) return unsafe.Pointer(stackDeltaInnerMap) case &C.unwind_info_array: diff --git a/tracehandler/tracehandler.go b/tracehandler/tracehandler.go index c1a6e391..ebc39ac0 100644 --- a/tracehandler/tracehandler.go +++ b/tracehandler/tracehandler.go @@ -126,6 +126,7 @@ func (m *traceHandler) HandleTrace(bpfTrace *host.Trace) { PID: bpfTrace.PID, TID: bpfTrace.TID, APMServiceName: "", // filled in below + CPU: bpfTrace.CPU, } if !m.reporter.SupportsReportTraceEvent() { diff --git a/tracer/events.go b/tracer/events.go index 0a29a9c4..7e21fe56 100644 --- a/tracer/events.go +++ b/tracer/events.go @@ -134,7 +134,7 @@ func startPerfEventMonitor(ctx context.Context, perfEventMap *ebpf.Map, // calls. Returns a function that can be called to retrieve perf event array // error counts. func startPollingPerfEventMonitor(ctx context.Context, perfEventMap *ebpf.Map, - pollFrequency time.Duration, perCPUBufferSize int, triggerFunc func([]byte), + pollFrequency time.Duration, perCPUBufferSize int, triggerFunc func([]byte, int), ) func() (lost, noData, readError uint64) { eventReader, err := perf.NewReader(perfEventMap, perCPUBufferSize) if err != nil { @@ -178,7 +178,7 @@ func startPollingPerfEventMonitor(ctx context.Context, perfEventMap *ebpf.Map, noDataCount.Add(1) continue } - triggerFunc(data.RawSample) + triggerFunc(data.RawSample, data.CPU) } } }() diff --git a/tracer/tracer.go b/tracer/tracer.go index 2da8bff5..78067738 100644 --- a/tracer/tracer.go +++ b/tracer/tracer.go @@ -841,7 +841,7 @@ func (t *Tracer) eBPFMetricsCollector( // // If the raw trace contains a kernel stack ID, the kernel stack is also // retrieved and inserted at the appropriate position. -func (t *Tracer) loadBpfTrace(raw []byte) *host.Trace { +func (t *Tracer) loadBpfTrace(raw []byte, cpu int) *host.Trace { frameListOffs := int(unsafe.Offsetof(C.Trace{}.frames)) if len(raw) < frameListOffs { @@ -863,6 +863,7 @@ func (t *Tracer) loadBpfTrace(raw []byte) *host.Trace { PID: libpf.PID(ptr.pid), TID: libpf.PID(ptr.tid), KTime: times.KTime(ptr.ktime), + CPU: cpu, } // Trace fields included in the hash: @@ -912,8 +913,8 @@ func (t *Tracer) StartMapMonitors(ctx context.Context, traceOutChan chan *host.T eventMetricCollector := t.startEventMonitor(ctx) startPollingPerfEventMonitor(ctx, t.ebpfMaps["trace_events"], t.intervals.TracePollInterval(), - t.samplesPerSecond*int(unsafe.Sizeof(C.Trace{})), func(rawTrace []byte) { - traceOutChan <- t.loadBpfTrace(rawTrace) + t.samplesPerSecond*int(unsafe.Sizeof(C.Trace{})), func(rawTrace []byte, cpu int) { + traceOutChan <- t.loadBpfTrace(rawTrace, cpu) }) pidEvents := make([]uint32, 0)