Skip to content

Commit

Permalink
fix(ebpf): python backport fixes (#3268)
Browse files Browse the repository at this point in the history
* fix(ebpf): fix glibc detection when the file name is libc-2.31.so instead of libc.so.6
* fix(ebpf): elf build id
  • Loading branch information
korniltsev authored May 6, 2024
1 parent e23c664 commit 5aed1e5
Show file tree
Hide file tree
Showing 10 changed files with 46 additions and 59 deletions.
12 changes: 7 additions & 5 deletions ebpf/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GO ?= go
RIDESHARE_REPO ?= korniltsev
RIDESHARE="testdata/rideshare-flask-no-pip"
RIDESHARE_REPO ?= pyroscope
RIDESHARE=testdata/rideshare-flask-no-pip

ifeq ($(shell uname -s),Linux)
ifeq ($(shell uname -m),x86_64)
Expand Down Expand Up @@ -29,12 +29,12 @@ python/dwarfdump:
git submodule update --init --recursive

echo "//go:build amd64 && linux" > python/python_offsets_gen_amd64.go
go run cmd/python_dwarfdump/main.go $(shell find testdata/python-x64 -name libpy\*.so\*) \
go run cmd/python_dwarfdump/main.go $(shell find testdata/python-x64 -name libpy\*.so\* | grep -v pyston) \
$(shell find testdata/python-x64 | grep -E "/python3\\.[0-9]+") >> python/python_offsets_gen_amd64.go
go fmt python/python_offsets_gen_amd64.go

echo "//go:build arm64 && linux" > python/python_offsets_gen_arm64.go
go run cmd/python_dwarfdump/main.go $(shell find testdata/python-arm64 -name libpy\*.so\*) \
go run cmd/python_dwarfdump/main.go $(shell find testdata/python-arm64 -name libpy\*.so\* | grep -v pyston) \
$(shell find testdata/python-arm64 | grep -E "/python3\\.[0-9]+") >> python/python_offsets_gen_arm64.go
go fmt python/python_offsets_gen_arm64.go

Expand Down Expand Up @@ -104,4 +104,6 @@ rideshare/gen:
docker buildx build --platform=linux/amd64,linux/arm64 --push -t $(RIDESHARE_REPO)/ebpf-testdata-rideshare:3.10-alpine --build-arg="PYTHON_VERSION=3.10-alpine" $(RIDESHARE)
docker buildx build --platform=linux/amd64,linux/arm64 --push -t $(RIDESHARE_REPO)/ebpf-testdata-rideshare:3.11-alpine --build-arg="PYTHON_VERSION=3.11-alpine" $(RIDESHARE)
docker buildx build --platform=linux/amd64,linux/arm64 --push -t $(RIDESHARE_REPO)/ebpf-testdata-rideshare:3.12-alpine --build-arg="PYTHON_VERSION=3.12-alpine" $(RIDESHARE)
docker buildx build --platform=linux/amd64,linux/arm64 --push -t $(RIDESHARE_REPO)/ebpf-testdata-rideshare:3.13-rc-alpine --build-arg="PYTHON_VERSION=3.13-rc-alpine" $(RIDESHARE)
docker buildx build --platform=linux/amd64,linux/arm64 --push -t $(RIDESHARE_REPO)/ebpf-testdata-rideshare:3.13-rc-alpine --build-arg="PYTHON_VERSION=3.13-rc-alpine" $(RIDESHARE)
docker buildx build --platform=linux/amd64,linux/arm64 --push -t $(RIDESHARE_REPO)/ebpf-testdata-rideshare:ubuntu-20.04 --build-arg="BASE=ubuntu:20.04" --build-arg="FLASK_VERSION=3.0.3" -f $(RIDESHARE)/ubuntu.Dockerfile $(RIDESHARE)
docker buildx build --platform=linux/amd64,linux/arm64 --push -t $(RIDESHARE_REPO)/ebpf-testdata-rideshare:ubuntu-22.04 --build-arg="BASE=ubuntu:22.04" --build-arg="FLASK_VERSION=3.0.3" -f $(RIDESHARE)/ubuntu.Dockerfile $(RIDESHARE)
2 changes: 1 addition & 1 deletion ebpf/cmd/python_dwarfdump/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ var pythonFields = []dwarfdump.Need{
{Name: "_typeobject", PrettyName: "PyTypeObject", Fields: []dwarfdump.NeedField{
{"tp_name", "PyTypeObject_tp_name"},
}},
{Name: "PyThreadState", Fields: []dwarfdump.NeedField{
{Name: "_ts", Fields: []dwarfdump.NeedField{
{"frame", "PyThreadState_frame"},
{"cframe", "PyThreadState_cframe"},
{"current_frame", "PyThreadState_current_frame"},
Expand Down
2 changes: 2 additions & 0 deletions ebpf/dwarfdump/dwarfdump.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"debug/dwarf"
"debug/elf"
"fmt"
"os"
"reflect"
"strings"
)
Expand Down Expand Up @@ -193,6 +194,7 @@ type FieldDump struct {
}

func Dump(elfPath string, fields []Need) []FieldDump {
fmt.Fprintf(os.Stderr, "Dumping %s\n", elfPath)
var err error

f, err := elf.Open(elfPath)
Expand Down
3 changes: 2 additions & 1 deletion ebpf/python/procinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package python
import (
"bufio"
"fmt"
"path/filepath"
"regexp"
"strconv"
"strings"
Expand Down Expand Up @@ -58,7 +59,7 @@ func GetProcInfo(s *bufio.Scanner) (ProcInfo, error) {
strings.Contains(m.Pathname, "/lib/ld-musl-aarch64.so.1") {
res.Musl = append(res.Musl, m)
}
if strings.HasSuffix(m.Pathname, "/libc.so.6") || strings.HasSuffix(m.Pathname, "/libc-2") {
if strings.HasSuffix(m.Pathname, "/libc.so.6") || strings.HasPrefix(filepath.Base(m.Pathname), "libc-2.") {
res.Glibc = append(res.Glibc, m)
}
}
Expand Down
4 changes: 4 additions & 0 deletions ebpf/python/procinfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsysca
info, err := GetProcInfo(bufio.NewScanner(bytes.NewReader([]byte(maps))))
require.NoError(t, err)
require.Nil(t, info.Musl)
require.NotNil(t, info.Glibc)
require.Equal(t, info.Version, Version{3, 6, 0})
require.NotNil(t, info.PythonMaps)
require.NotNil(t, info.LibPythonMaps)
Expand Down Expand Up @@ -116,6 +117,7 @@ ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsysca
info, err = GetProcInfo(bufio.NewScanner(bytes.NewReader([]byte(maps))))
require.NoError(t, err)
require.NotNil(t, info.Musl)
require.Nil(t, info.Glibc)
require.Equal(t, info.Version, Version{3, 11, 0})
require.NotNil(t, info.PythonMaps)
require.NotNil(t, info.LibPythonMaps)
Expand All @@ -128,6 +130,7 @@ ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsysca
info, err = GetProcInfo(bufio.NewScanner(bytes.NewReader([]byte(maps))))
require.NoError(t, err)
require.Nil(t, info.Musl)
require.Nil(t, info.Glibc)
require.Equal(t, info.Version, Version{3, 7, 0})
require.NotNil(t, info.PythonMaps)
require.Nil(t, info.LibPythonMaps)
Expand Down Expand Up @@ -160,6 +163,7 @@ fffff8c25000-fffff8c53000 rw-p 00000000 00:00 0 [stack]
info, err = GetProcInfo(bufio.NewScanner(bytes.NewReader([]byte(maps))))
require.NoError(t, err)
require.Nil(t, info.Musl)
require.NotNil(t, info.Glibc)
require.Equal(t, info.Version, Version{3, 8, 0})
require.Nil(t, info.PythonMaps)
require.NotNil(t, info.LibPythonMaps)
Expand Down
8 changes: 4 additions & 4 deletions ebpf/python/python_offsets_gen_amd64.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 4 additions & 35 deletions ebpf/python/python_offsets_gen_arm64.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions ebpf/python3_ebpf_expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
python3;server.py <module>;app.py Flask.run;serving.py run_simple;serving.py BaseWSGIServer.serve_forever;socketserver.py BaseWSGIServer.serve_forever;socketserver.py BaseWSGIServer._handle_request_noblock;socketserver.py BaseWSGIServer.process_request;socketserver.py BaseWSGIServer.finish_request;socketserver.py WSGIRequestHandler.__init__;serving.py WSGIRequestHandler.handle;server.py WSGIRequestHandler.handle;server.py WSGIRequestHandler.handle_one_request;serving.py NullCls.run_wsgi;serving.py execute;app.py Flask.__call__;app.py Flask.wsgi_app;app.py Flask.full_dispatch_request;app.py Flask.dispatch_request;server.py bike;bike.py order_bike;utility.py find_nearest_vehicle
python3;server.py <module>;app.py Flask.run;serving.py run_simple;serving.py BaseWSGIServer.serve_forever;socketserver.py BaseWSGIServer.serve_forever;socketserver.py BaseWSGIServer._handle_request_noblock;socketserver.py BaseWSGIServer.process_request;socketserver.py BaseWSGIServer.finish_request;socketserver.py WSGIRequestHandler.__init__;serving.py WSGIRequestHandler.handle;server.py WSGIRequestHandler.handle;server.py WSGIRequestHandler.handle_one_request;serving.py NullCls.run_wsgi;serving.py execute;app.py Flask.__call__;app.py Flask.wsgi_app;app.py Flask.full_dispatch_request;app.py Flask.dispatch_request;server.py car;car.py order_car;utility.py find_nearest_vehicle
python3;server.py <module>;app.py Flask.run;serving.py run_simple;serving.py BaseWSGIServer.serve_forever;socketserver.py BaseWSGIServer.serve_forever;socketserver.py BaseWSGIServer._handle_request_noblock;socketserver.py BaseWSGIServer.process_request;socketserver.py BaseWSGIServer.finish_request;socketserver.py WSGIRequestHandler.__init__;serving.py WSGIRequestHandler.handle;server.py WSGIRequestHandler.handle;server.py WSGIRequestHandler.handle_one_request;serving.py NullCls.run_wsgi;serving.py execute;app.py Flask.__call__;app.py Flask.wsgi_app;app.py Flask.full_dispatch_request;app.py Flask.dispatch_request;server.py car;car.py order_car;utility.py find_nearest_vehicle;utility.py check_driver_availability
python3;server.py <module>;app.py Flask.run;serving.py run_simple;serving.py BaseWSGIServer.serve_forever;socketserver.py BaseWSGIServer.serve_forever;socketserver.py BaseWSGIServer._handle_request_noblock;socketserver.py BaseWSGIServer.process_request;socketserver.py BaseWSGIServer.finish_request;socketserver.py WSGIRequestHandler.__init__;serving.py WSGIRequestHandler.handle;server.py WSGIRequestHandler.handle;server.py WSGIRequestHandler.handle_one_request;serving.py NullCls.run_wsgi;serving.py execute;app.py Flask.__call__;app.py Flask.wsgi_app;app.py Flask.full_dispatch_request;app.py Flask.dispatch_request;server.py scooter;scooter.py order_scooter;utility.py find_nearest_vehicle
29 changes: 17 additions & 12 deletions ebpf/python_ebpf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,28 @@ var pythonEBPFExpected []byte
//go:embed python_ebpf_expected_3.11.txt
var pythonEBPFExpected311 []byte

//go:embed python3_ebpf_expected.txt
var python3EBPFExpected []byte

func TestEBPFPythonProfiler(t *testing.T) {
var testdata = []struct {
image string
expected []byte
}{
{"korniltsev/ebpf-testdata-rideshare:3.8-slim", pythonEBPFExpected},
{"korniltsev/ebpf-testdata-rideshare:3.9-slim", pythonEBPFExpected},
{"korniltsev/ebpf-testdata-rideshare:3.10-slim", pythonEBPFExpected},
{"korniltsev/ebpf-testdata-rideshare:3.11-slim", pythonEBPFExpected311},
{"korniltsev/ebpf-testdata-rideshare:3.12-slim", pythonEBPFExpected311},
{"korniltsev/ebpf-testdata-rideshare:3.13-rc-slim", pythonEBPFExpected311},
{"korniltsev/ebpf-testdata-rideshare:3.8-alpine", pythonEBPFExpected},
{"korniltsev/ebpf-testdata-rideshare:3.9-alpine", pythonEBPFExpected},
{"korniltsev/ebpf-testdata-rideshare:3.10-alpine", pythonEBPFExpected},
{"korniltsev/ebpf-testdata-rideshare:3.11-alpine", pythonEBPFExpected311},
{"korniltsev/ebpf-testdata-rideshare:3.12-alpine", pythonEBPFExpected311},
{"korniltsev/ebpf-testdata-rideshare:3.13-rc-alpine", pythonEBPFExpected311},
{"pyroscope/ebpf-testdata-rideshare:3.8-slim", pythonEBPFExpected},
{"pyroscope/ebpf-testdata-rideshare:3.9-slim", pythonEBPFExpected},
{"pyroscope/ebpf-testdata-rideshare:3.10-slim", pythonEBPFExpected},
{"pyroscope/ebpf-testdata-rideshare:3.11-slim", pythonEBPFExpected311},
{"pyroscope/ebpf-testdata-rideshare:3.12-slim", pythonEBPFExpected311},
{"pyroscope/ebpf-testdata-rideshare:3.13-rc-slim", pythonEBPFExpected311},
{"pyroscope/ebpf-testdata-rideshare:3.8-alpine", pythonEBPFExpected},
{"pyroscope/ebpf-testdata-rideshare:3.9-alpine", pythonEBPFExpected},
{"pyroscope/ebpf-testdata-rideshare:3.10-alpine", pythonEBPFExpected},
{"pyroscope/ebpf-testdata-rideshare:3.11-alpine", pythonEBPFExpected311},
{"pyroscope/ebpf-testdata-rideshare:3.12-alpine", pythonEBPFExpected311},
{"pyroscope/ebpf-testdata-rideshare:3.13-rc-alpine", pythonEBPFExpected311},
{"pyroscope/ebpf-testdata-rideshare:ubuntu-20.04", python3EBPFExpected},
{"pyroscope/ebpf-testdata-rideshare:ubuntu-22.04", python3EBPFExpected},
}

const ridesharePort = "5000"
Expand Down
2 changes: 1 addition & 1 deletion ebpf/symtab/elf/buildid.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (f *MMapedElfFile) GNUBuildID() (BuildID, error) {
return BuildID{}, fmt.Errorf(".note.gnu.build-id is not a GNU build-id : %s", hex.EncodeToString(data))
}
rawBuildID := data[16:]
if len(rawBuildID) != 20 && len(rawBuildID) != 8 { // 8 is xxhash, for example in Container-Optimized OS
if len(rawBuildID) < 8 {
return BuildID{}, fmt.Errorf(".note.gnu.build-id has wrong size %s : %s ", f.fpath, hex.EncodeToString(data))
}
buildIDHex := hex.EncodeToString(rawBuildID)
Expand Down

0 comments on commit 5aed1e5

Please sign in to comment.