Skip to content

fix(ebpf): python backport fixes #3268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 6, 2024
Merged
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
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.") {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the main change for "libc not found" error fix

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 {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the change for fixing ".note.gnu.build-id has wrong size" when gnu build id is 8 bytes long

return BuildID{}, fmt.Errorf(".note.gnu.build-id has wrong size %s : %s ", f.fpath, hex.EncodeToString(data))
}
buildIDHex := hex.EncodeToString(rawBuildID)
Expand Down