From 319cf1d69c2063de13bebe58909bc5e7314b762c Mon Sep 17 00:00:00 2001 From: keisku Date: Mon, 16 Sep 2024 00:14:40 +0000 Subject: [PATCH 1/4] Fix offset of goid Signed-off-by: keisku --- ebpf/c/gmon.c | 4 ++-- ebpf/c/goroutine.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ebpf/c/gmon.c b/ebpf/c/gmon.c index 7f68569..30373cd 100644 --- a/ebpf/c/gmon.c +++ b/ebpf/c/gmon.c @@ -24,9 +24,9 @@ int runtime_newproc1(struct pt_regs *ctx) { bpf_printk("%s:%d | failed to extract new goroutine pointer from retval\n", __FILE__, __LINE__); return 0; } - // `pahole -C runtime.g /path/to/gobinary 2>/dev/null` shows the offsets of the goid which is 152. + // `pahole -C runtime.g /path/to/gobinary 2>/dev/null` shows the offsets of the goid. int64_t goid = 0; - if (bpf_core_read_user(&goid, sizeof(int64_t), newg_p + 152)) { + if (bpf_core_read_user(&goid, sizeof(int64_t), newg_p + 160)) { bpf_printk("%s:%d | failed to read goroutine id from newg with the offset\n", __FILE__, __LINE__); return 0; } diff --git a/ebpf/c/goroutine.h b/ebpf/c/goroutine.h index 8ba80c0..4f7a271 100644 --- a/ebpf/c/goroutine.h +++ b/ebpf/c/goroutine.h @@ -18,7 +18,7 @@ struct gobuf_t { uintptr_t bp; }; -// https://github.com/golang/go/blob/release-branch.go1.21/src/runtime/runtime2.go#L447 +// https://github.com/golang/go/blob/release-branch.go1.23/src/runtime/runtime2.go#L458 struct g_t { struct stack_t stack_instance; uintptr_t stackguard0; @@ -29,6 +29,7 @@ struct g_t { struct gobuf_t sched; uintptr_t syscallsp; uintptr_t syscallpc; + uintptr_t syscallbp; uintptr_t stktopsp; uintptr_t param; uint32_t atomicstatus; From af4223dc8dd73510c260b676f377220ddf2ca8be Mon Sep 17 00:00:00 2001 From: keisku Date: Mon, 16 Sep 2024 00:18:36 +0000 Subject: [PATCH 2/4] Bump Go version Signed-off-by: keisku --- fixture/go.mod | 2 +- gmon.sh | 2 +- go.mod | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fixture/go.mod b/fixture/go.mod index 49a1fda..828d4a1 100644 --- a/fixture/go.mod +++ b/fixture/go.mod @@ -1,3 +1,3 @@ module fixture -go 1.22.1 +go 1.23.1 diff --git a/gmon.sh b/gmon.sh index 8d1b6fd..f1df66e 100755 --- a/gmon.sh +++ b/gmon.sh @@ -43,7 +43,7 @@ ln -s /usr/bin/llvm-strip-14 /usr/bin/llvm-strip ln -s /usr/bin/clang-14 /usr/bin/clang ln -s /usr/bin/clang-format-14 /usr/bin/clang-format wget -O- --no-check-certificate https://github.com/libbpf/bpftool/releases/download/v7.3.0/bpftool-v7.3.0-amd64.tar.gz | tar -xzf - -C /usr/bin && chmod +x /usr/bin/bpftool -wget -O- --no-check-certificate https://go.dev/dl/go1.22.3.linux-amd64.tar.gz | tar -xzf - -C /usr/local && chmod +x /usr/local/go/bin/go && ln -s /usr/local/go/bin/go /usr/bin/go +wget -O- --no-check-certificate https://go.dev/dl/go1.23.1.linux-amd64.tar.gz | tar -xzf - -C /usr/local && chmod +x /usr/local/go/bin/go && ln -s /usr/local/go/bin/go /usr/bin/go END WORKDIR /usr/src COPY go.mod go.mod diff --git a/go.mod b/go.mod index 419c9f9..08102e1 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/keisku/gmon -go 1.22.3 +go 1.23.1 require ( github.com/cilium/ebpf v0.15.0 From 2929f76eaa39dfcc510ad5e7de43676d4e765319 Mon Sep 17 00:00:00 2001 From: keisku Date: Mon, 16 Sep 2024 00:18:45 +0000 Subject: [PATCH 3/4] Clarify Go version requirement of target binary Signed-off-by: keisku --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7bc554d..eafeebf 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ - amd64 (x86_64) - Linux Kernel 5.8+ since `gmon` uses [BPF ring buffer](https://nakryiko.com/posts/bpf-ringbuf/) +- Target Go binary must be compiled with Go 1.23+ since `gmon` uses fixed offset to get goroutine ID # Usage From ea94ffad78fc52792cada58ed2f5e7b66ae7c2a2 Mon Sep 17 00:00:00 2001 From: keisku Date: Mon, 16 Sep 2024 00:34:39 +0000 Subject: [PATCH 4/4] return error if go version of target is less than 1.23 Signed-off-by: keisku --- main.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/main.go b/main.go index ee523ef..963c1dd 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "bufio" "context" + "debug/buildinfo" "errors" "flag" "fmt" @@ -16,6 +17,7 @@ import ( "runtime" "runtime/debug" "runtime/trace" + "strconv" "strings" "github.com/cilium/ebpf/rlimit" @@ -87,6 +89,14 @@ func main() { errlog.Fatalln("gmon only works on amd64 Linux") } + binfo, err := buildinfo.ReadFile(*binPath) + if err != nil { + errlog.Fatalln(err) + } + if !isGoVersion123OrHigher(binfo.GoVersion) { + errlog.Fatalf("gmon requires Go 1.23 or higher, but %s is used for %s", binfo.GoVersion, binfo.Main.Path) + } + if *traceOutPath != "" { traceOutFile, err := os.Create(*traceOutPath) if err != nil { @@ -161,3 +171,21 @@ func logTracePipe(done <-chan struct{}) { }() <-done } + +func isGoVersion123OrHigher(v string) bool { + versionSplit := strings.Split(v, ".") + if len(versionSplit) != 3 { + return false + } + if versionSplit[0] != "go1" { + return false + } + minor, err := strconv.Atoi(versionSplit[1]) + if err != nil { + return false + } + if minor < 23 { + return false + } + return true +}