agiledragon / agiledragon/gomonkey

MacOS m3 打桩失败bug

Abierto
#171 2 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Go
Estrellas
2.3k
Forks
192
Merge medio
1 d 6 h
PR fusionados (30 d)
1

Descripción

## 环境
MacOS: 14.6
GO版本: go1.21.13 (也测试了go1.18版本也有问题)
M3芯片
gomonkey版本: v2.12.0
## 问题描述
在一个测试用例中对同一个函数进行打桩、取消、再打桩,后续的打桩可能会失败。以下为测试代码,可以直接拷贝执行验证的
``` golang
type funcValue struct {
_ uintptr
p unsafe.Pointer
}

func getPointer(v reflect.Value) unsafe.Pointer {
return (*funcValue)(unsafe.Pointer(&v)).p
}

func entryAddress(p uintptr, l int) []byte {
return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{Data: p, Len: l, Cap: l}))
}

func target() {
fmt.Println("origin func invoked")
}

// func24Byte 此函数将函数对应的代码code前24个字节打印出来,方便观察打桩是否生效了
func func24Byte(fn interface{}) {
v := reflect.ValueOf(fn)
pp := *(*uintptr)(getPointer(v))
addr := entryAddress(pp, 24)
fmt.Printf("代码code:%x\n", addr)
}

func TestBBB(t *testing.T) {
p := gomonkey.NewPatches()
pause := true // 控制每次打桩后是否需要sleep,sleep会影响打桩是否生效,sleep后打桩稳定生效,不sleep打桩不一定会生效
// 输出原始函数
fmt.Println("expect origin func:")
target()
func24Byte(target)

// 第一次打桩
p.ApplyFunc(target, func() {
fmt.Println("double func invoked")
})
if pause {
time.Sleep(time.Millisecond)
}
fmt.Println("expect double func")
target()
func24Byte(target)

// 恢复
p.Reset()
if pause {
time.Sleep(time.Millisecond)
}
fmt.Println("expect origin func")
target()
func24Byte(target)

// 第二次打桩
p2 := gomonkey.NewPatches()
p2.ApplyFunc(target, func() {
fmt.Println("three func invoked")
})
if pause {
time.Sleep(time.Millisecond)
}
fmt.Println("expect three func")
target()
func24Byte(target)

// 恢复
p2.Reset()
if pause {
time.Sleep(time.Millisecond)
}
fmt.Println("expect origin func")
target()
func24Byte(target)
}
```
当使用pause=true 执行测试时,测试完美执行,执行结果如下:
image
但是当运行pause=false时,测试结果如下:
image

我耗费两天观察这个问题,依然百思不得其解,为什么代码区字节码都被改写了,funcValue的调用依然不生效呢,辛苦各位大佬帮忙看下@agiledragon

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.