Skip to content

Commit

Permalink
deps: bump libbpfgo
Browse files Browse the repository at this point in the history
Signed-off-by: Massimiliano Giovagnoli <me@maxgio.it>
  • Loading branch information
maxgio92 committed Apr 12, 2024
1 parent 3e8797b commit 8c223fe
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 72 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.idea
/perf-profiler-go
/output
/libbpfgo
*.o
vmlinux.h
74 changes: 68 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,72 @@
PROGRAM := profiler

# dependencies

git = $(shell command -v git || /bin/false)
bpftool = $(shell command -v bpftool || /bin/false)

# general

mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
current_dir := $(patsubst %/,%,$(dir $(mkfile_path)))
OUTPUT := $(current_dir)/output

ARCH := $(subst x86_64,x86,$(shell uname -m))
GOARCH := $(subst x86,amd64,$(ARCH))

# ebpf

VMLINUXH := vmlinux.h
BTFFILE := /sys/kernel/btf/vmlinux

CFLAGS ?= -D__TARGET_ARCH_$(ARCH)

.PHONY: probe
probe: vmlinux.h
clang $(CFLAGS) -g -O2 -c -target bpf -o kernel/profile.o kernel/profile.c
# libbpfgo

LIBBPFGO_GIT := https://github.com/aquasecurity/libbpfgo.git
LIBBPFGO := libbpfgo

# frontend

CGO_CFLAGS = "-I $(current_dir)/$(LIBBPFGO)/output"
CGO_LDFLAGS = "-lelf -lz $(current_dir)/$(LIBBPFGO)/output/libbpf.a"

.PHONY: $(PROGRAM)
$(PROGRAM): $(LIBBPFGO) | $(PROGRAM)/bpf
CC=gcc \
CGO_CFLAGS=$(CGO_CFLAGS) \
CGO_LDFLAGS=$(CGO_LDFLAGS) \
GOARCH=$(GOARCH) \
go build -v \
-o ${OUTPUT}/${PROGRAM} .

.PHONY: $(PROGRAM)/bpf
$(PROGRAM)/bpf: vmlinux.h
clang $(CFLAGS) -g -O2 -c -target bpf -o $(OUTPUT)/profile.o kernel/profile.c

.PHONY: $(LIBBPFGO)
$(LIBBPFGO):
$(git) clone $(LIBBPFGO_GIT) && \
make -C $(LIBBPFGO) libbpfgo-static

.PHONY: $(VMLINUXH)
$(VMLINUXH): $(OUTPUT)
ifeq ($(wildcard $(bpftool)),)
@echo "ERROR: could not find bpftool"
@exit 1
endif
@if [ ! -f $(BTFFILE) ]; then \
echo "ERROR: kernel does not seem to support BTF"; \
exit 1; \
fi
@if [ ! -f $(VMLINUXH) ]; then \
echo "INFO: generating $(VMLINUXH) from $(BTFFILE)"; \
$(bpftool) btf dump file $(BTFFILE) format c > kernel/$(VMLINUXH); \
fi

$(OUTPUT):
mkdir -p $(OUTPUT)

.PHONY: vmlinux.h
vmlinux.h:
bpftool btf dump file /sys/kernel/btf/vmlinux format c > kernel/vmlinux.h
clean:
rm -rf $(OUTPUT)
rm -rf $(LIBBPFGO)
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ module github.com/maxgio92/perf-profiler-go
go 1.21.1

require (
github.com/aquasecurity/tracee/libbpfgo v0.0.0-20210518164823-94530727cde4
github.com/pkg/errors v0.9.1
golang.org/x/sys v0.14.0
)

require (
github.com/aquasecurity/libbpfgo v0.6.0-libbpf-1.3 // indirect
github.com/stretchr/testify v1.8.4 // indirect
)
13 changes: 8 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
github.com/aquasecurity/tracee/libbpfgo v0.0.0-20210518164823-94530727cde4 h1:46arhhxBEYn4SaVliz7bZwVGRrdYUbiVEYNW0kESnnY=
github.com/aquasecurity/tracee/libbpfgo v0.0.0-20210518164823-94530727cde4/go.mod h1:PgXimFYUSx0PfQFRIyl770Jowy6O3r7iJOr39dt1bss=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/aquasecurity/libbpfgo v0.6.0-libbpf-1.3 h1:mhDe1mAZR80LjnsCnteS+R2/EeBFi9qFjKslsIJwVSo=
github.com/aquasecurity/libbpfgo v0.6.0-libbpf-1.3/go.mod h1:0rEApF1YBHGuZ4C8OYI9q5oDBVpgqtRqYATePl9mCDk=
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/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
45 changes: 45 additions & 0 deletions pkg/profile/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package profile

type ProfileOption func(profile *Profile)

func WithPID(pid int) ProfileOption {
return func(t *Profile) {
t.pid = pid
}
}

func WithDuration(duration int) ProfileOption {
return func(t *Profile) {
t.duration = duration
}
}

func WithSamplingPeriodMillis(period uint64) ProfileOption {
return func(t *Profile) {
t.samplingPeriodMillis = period
}
}

func WithProbeFilepath(path string) ProfileOption {
return func(t *Profile) {
t.probeFilepath = path
}
}

func WithProbeName(name string) ProfileOption {
return func(t *Profile) {
t.probeName = name
}
}

func WithMapStackTraces(name string) ProfileOption {
return func(t *Profile) {
t.mapStackTraces = name
}
}

func WithMapHistogram(name string) ProfileOption {
return func(t *Profile) {
t.mapHistogram = name
}
}
68 changes: 9 additions & 59 deletions pkg/profile/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"log"
"unsafe"

bpf "github.com/aquasecurity/tracee/libbpfgo"
bpf "github.com/aquasecurity/libbpfgo"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
)
Expand Down Expand Up @@ -36,50 +36,6 @@ type Profile struct {
mapHistogram string
}

type ProfileOption func(profile *Profile)

func WithPID(pid int) ProfileOption {
return func(t *Profile) {
t.pid = pid
}
}

func WithDuration(duration int) ProfileOption {
return func(t *Profile) {
t.duration = duration
}
}

func WithSamplingPeriodMillis(period uint64) ProfileOption {
return func(t *Profile) {
t.samplingPeriodMillis = period
}
}

func WithProbeFilepath(path string) ProfileOption {
return func(t *Profile) {
t.probeFilepath = path
}
}

func WithProbeName(name string) ProfileOption {
return func(t *Profile) {
t.probeName = name
}
}

func WithMapStackTraces(name string) ProfileOption {
return func(t *Profile) {
t.mapStackTraces = name
}
}

func WithMapHistogram(name string) ProfileOption {
return func(t *Profile) {
t.mapHistogram = name
}
}

func NewProfile(opts ...ProfileOption) *Profile {
profile := new(Profile)
for _, f := range opts {
Expand All @@ -89,16 +45,7 @@ func NewProfile(opts ...ProfileOption) *Profile {
return profile
}

func (t *Profile) validate() error {
// TODO
return nil
}

func (t *Profile) RunProfile() error {
if err := t.validate(); err != nil {
return errors.Wrap(err, "error running profile")
}

bpfModule, err := bpf.NewModuleFromFile(t.probeFilepath)
if err != nil {
return errors.Wrap(err, "error creating the BPF module object")
Expand Down Expand Up @@ -153,7 +100,7 @@ func (t *Profile) RunProfile() error {
-1,

// The program file descriptor.
prog.GetFd(),
prog.FileDescriptor(),
)
if err != nil {
return errors.Wrap(err, "error creating the perf event")
Expand All @@ -165,7 +112,7 @@ func (t *Profile) RunProfile() error {
}()

// Attach the BPF program to the sampling perf event.
if _, err = prog.AttachPerfEvent(prog.GetFd()); err != nil {
if _, err = prog.AttachPerfEvent(prog.FileDescriptor()); err != nil {
return errors.Wrap(err, "error attaching the BPF probe to the sampling perf event")
}

Expand All @@ -182,9 +129,9 @@ func (t *Profile) RunProfile() error {
// Iterate over the stack profile counts histogram map.
result := make(map[string]int, 0)

for it := histogram.Iterator(int(unsafe.Sizeof(&HistogramKey{}))); it.Next(); {
for it := histogram.Iterator(); it.Next(); {
k := it.Key()
count, err := histogram.GetValue(k, len(k))
count, err := histogram.GetValue(unsafe.Pointer(&k))
if err != nil {
return errors.Wrap(err, fmt.Sprintf("error getting stack profile count for key %v", k))
}
Expand All @@ -199,6 +146,9 @@ func (t *Profile) RunProfile() error {
continue
}

fmt.Printf("%v\t%v\t\t", key.Pid, binary.LittleEndian.Uint64(count))
fmt.Printf("%v\t\t", key.KernelStackId)

var symbols string

if key.KernelStackId != 0 {
Expand Down Expand Up @@ -230,7 +180,7 @@ func getStackTrace(stackTracesMap *bpf.BPFMap, id uint32) (*StackTrace, error) {
key := make([]byte, 4)
binary.LittleEndian.PutUint32(key, id)

stackBinary, err := stackTracesMap.GetValue(key, int(unsafe.Sizeof(&StackTrace{})))
stackBinary, err := stackTracesMap.GetValue(unsafe.Pointer(&key))
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 8c223fe

Please sign in to comment.