-
Notifications
You must be signed in to change notification settings - Fork 182
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
MacOS m3 打桩失败bug #171
Comments
遇到了相同的二次打桩失败问题。 环境: |
原因是因为apple silicon芯片默认会有指令缓存的功能,在Reset里面需要增加清空指令缓存,可以通过CGO使用 /*
#include <stdlib.h>
// 使用 Clang 的内置函数刷新指令缓存
void flush_instruction_cache(void *addr, size_t size) {
__builtin___clear_cache((char*)addr, (char*)addr + size);
}
*/
import "C"
import (
"reflect"
"unsafe"
)
// 需要使用 cgo 或其他方法调用底层汇编指令
func flushInstructionCache(v any, method string, size uintptr) {
// 实现汇编指令刷新缓存
m, _ := reflect.TypeOf(v).MethodByName(method)
addr := unsafe.Pointer(m.Func.Pointer())
C.flush_instruction_cache(addr, C.size_t(size))
} 实验: 未刷新type BBB struct {
v string
}
func (b *BBB) Value() string {
return b.v
}
func TestBBBValue(t *testing.T) {
b1 := &BBB{
v: "b1",
}
// 没有修改
assert.Equal(t, "b1", b1.Value())
// 修改
p := gomonkey.ApplyMethodReturn(b1, "Value", "test_b1")
assert.Equal(t, "test_b1", b1.Value())
p.Reset()
//flushInstructionCache(b1, "Value", 24)
// 再次修改
p = gomonkey.ApplyMethodReturn(b1, "Value", "test_b2")
assert.Equal(t, "test_b2", b1.Value())
p.Reset()
//flushInstructionCache(b1, "Value", 24)
assert.Equal(t, "b1", b1.Value())
} 会报错:
这个不固定,因为有两次Reset都可能随机出现问题,比如还有可能:
把对应刷新的注释关闭,怎么测试都可以了:func TestBBBValue(t *testing.T) {
b1 := &BBB{
v: "b1",
}
// 没有修改
assert.Equal(t, "b1", b1.Value())
// 修改
p := gomonkey.ApplyMethodReturn(b1, "Value", "test_b1")
assert.Equal(t, "test_b1", b1.Value())
p.Reset()
flushInstructionCache(b1, "Value", 24) // <--- 这里
// 再次修改
p = gomonkey.ApplyMethodReturn(b1, "Value", "test_b2")
assert.Equal(t, "test_b2", b1.Value())
p.Reset()
flushInstructionCache(b1, "Value", 24) // <--- 这里
assert.Equal(t, "b1", b1.Value())
} 测试通过:
@liracle @agiledragon 供参考。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
环境
MacOS: 14.6
GO版本: go1.21.13 (也测试了go1.18版本也有问题)
M3芯片
gomonkey版本: v2.12.0
问题描述
在一个测试用例中对同一个函数进行打桩、取消、再打桩,后续的打桩可能会失败。以下为测试代码,可以直接拷贝执行验证的
当使用pause=true 执行测试时,测试完美执行,执行结果如下:
但是当运行pause=false时,测试结果如下:
我耗费两天观察这个问题,依然百思不得其解,为什么代码区字节码都被改写了,funcValue的调用依然不生效呢,辛苦各位大佬帮忙看下@agiledragon
The text was updated successfully, but these errors were encountered: