From 196812bdfbc5e7084faf17cd434df186dc56cffb Mon Sep 17 00:00:00 2001 From: TimAndy Date: Wed, 14 Aug 2024 18:19:16 +0800 Subject: [PATCH] Not support refer to internal symbols in the standard library anymore, as the linker have changed since go1.23 --- g/g.go | 12 ------------ g/g_test.go | 18 +++++++++--------- gohack_test.go | 24 +++++++++++++++++++++--- runtime.go | 5 ----- runtime_test.go | 22 +++++++++++++--------- 5 files changed, 43 insertions(+), 38 deletions(-) diff --git a/g/g.go b/g/g.go index 97e677e..1f62e75 100644 --- a/g/g.go +++ b/g/g.go @@ -8,23 +8,11 @@ import ( "unsafe" ) -// g0 the value of runtime.g0. -// -//go:linkname g0 runtime.g0 -var g0 struct{} - // getgp returns the pointer to the current runtime.g. // //go:nosplit func getgp() unsafe.Pointer -// getg0 returns the value of runtime.g0. -// -//go:nosplit -func getg0() interface{} { - return packEface(getgt(), unsafe.Pointer(&g0)) -} - // getgt returns the type of runtime.g. // //go:nosplit diff --git a/g/g_test.go b/g/g_test.go index 2e58bf9..dfea56f 100644 --- a/g/g_test.go +++ b/g/g_test.go @@ -25,15 +25,6 @@ func TestGetgp(t *testing.T) { }) } -func TestGetg0(t *testing.T) { - runTest(t, func() { - g := getg0() - runtime.GC() - stackguard0 := reflect.ValueOf(g).FieldByName("stackguard0") - assert.Greater(t, stackguard0.Uint(), uint64(0)) - }) -} - func TestGetgt(t *testing.T) { runTest(t, func() { gt := getgt() @@ -44,6 +35,15 @@ func TestGetgt(t *testing.T) { }) } +func TestGetg(t *testing.T) { + runTest(t, func() { + g := packEface(getgt(), getgp()) + runtime.GC() + stackguard0 := reflect.ValueOf(g).FieldByName("stackguard0") + assert.Greater(t, stackguard0.Uint(), uint64(0)) + }) +} + func runTest(t *testing.T, fun func()) { run := false wg := &sync.WaitGroup{} diff --git a/gohack_test.go b/gohack_test.go index 83ff854..3c92996 100644 --- a/gohack_test.go +++ b/gohack_test.go @@ -1,14 +1,19 @@ package gohack import ( + "bytes" + "fmt" "reflect" "runtime" + "strconv" "testing" "unsafe" "github.com/stretchr/testify/assert" ) +var goroutineSpace = []byte("goroutine ") + func TestG_Goid(t *testing.T) { runTest(t, func() { gp := getg() @@ -97,9 +102,22 @@ func TestOffset(t *testing.T) { } // curGoroutineID parse the current g's goid from caller stack. -// -//go:linkname curGoroutineID net/http.http2curGoroutineID -func curGoroutineID() int64 +func curGoroutineID() int64 { + b := make([]byte, 64) + b = b[:runtime.Stack(b, false)] + // Parse the 4707 out of "goroutine 4707 [" + b = bytes.TrimPrefix(b, goroutineSpace) + i := bytes.IndexByte(b, ' ') + if i < 0 { + panic(fmt.Sprintf("No space found in %q", b)) + } + b = b[:i] + n, err := strconv.ParseInt(string(b), 10, 64) + if err != nil { + panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", b, err)) + } + return n +} // setPanicOnFault controls the runtime's behavior when a program faults at an unexpected (non-nil) address. // diff --git a/runtime.go b/runtime.go index a050335..e75056b 100644 --- a/runtime.go +++ b/runtime.go @@ -12,11 +12,6 @@ import ( //go:linkname getgp github.com/timandy/gohack/g.getgp func getgp() unsafe.Pointer -// getg0 returns the value of runtime.g0. -// -//go:linkname getg0 github.com/timandy/gohack/g.getg0 -func getg0() interface{} - // getgt returns the type of runtime.g. // //go:linkname getgt github.com/timandy/gohack/g.getgt diff --git a/runtime_test.go b/runtime_test.go index 874e997..7440626 100644 --- a/runtime_test.go +++ b/runtime_test.go @@ -8,10 +8,14 @@ import ( "sync" "sync/atomic" "testing" + "unsafe" "github.com/stretchr/testify/assert" ) +//go:linkname packEface github.com/timandy/gohack/g.packEface +func packEface(typ reflect.Type, p unsafe.Pointer) (i interface{}) + func TestGetgp(t *testing.T) { gp0 := getgp() runtime.GC() @@ -25,15 +29,6 @@ func TestGetgp(t *testing.T) { }) } -func TestGetg0(t *testing.T) { - runTest(t, func() { - g0 := getg0() - runtime.GC() - stackguard0 := reflect.ValueOf(g0).FieldByName("stackguard0") - assert.Greater(t, stackguard0.Uint(), uint64(0)) - }) -} - func TestGetgt(t *testing.T) { fmt.Println("*** GOOS:", runtime.GOOS, "***") fmt.Println("*** GOARCH:", runtime.GOARCH, "***") @@ -73,6 +68,15 @@ func TestGetgt(t *testing.T) { }) } +func TestGetg(t *testing.T) { + runTest(t, func() { + g0 := packEface(getgt(), getgp()) + runtime.GC() + stackguard0 := reflect.ValueOf(g0).FieldByName("stackguard0") + assert.Greater(t, stackguard0.Uint(), uint64(0)) + }) +} + func runTest(t *testing.T, fun func()) { var count int32 wg := &sync.WaitGroup{}