Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.25"
go-version: "1.26"
- name: Unit Test
run: go test -gcflags="all=-l -N" -coverprofile=coverage.txt -timeout 30s -count 1 ./...
- name: Upload results to Codecov
Expand Down
10 changes: 8 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ jobs:
unit-benchmark-test-no-race: # some go version -race has fatal issues
strategy:
matrix:
go: ["1.14", "1.15", "1.16", "1.17"]
go: [
"1.14",
"1.15",
"1.16",
"1.17",
"1.26" # go1.26 has fatal issues with -race
]
os: [linux] # should be [ macOS, linux, windows ], but currently we don't have macOS and windows runners
arch: [X64, ARM64]
exclude:
Expand All @@ -65,7 +71,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: "1.25"
go-version: "1.26"
- name: Unit Test
run: MOCKEY_DEBUG=true go test -gcflags="all=-l -N" -timeout 30s -count 1 -tags mockey_disable_ss,mockey_disable_stw ./...
- name: Benchmark
Expand Down
4 changes: 2 additions & 2 deletions internal/fn/analyzer_1_20.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build go1.20 && !go1.26
// +build go1.20,!go1.26
//go:build go1.20 && !go1.27
// +build go1.20,!go1.27

/*
* Copyright 2022 ByteDance Inc.
Expand Down
4 changes: 2 additions & 2 deletions internal/fn/name_analyzer_1_20.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build go1.20 && !go1.26
// +build go1.20,!go1.26
//go:build go1.20 && !go1.27
// +build go1.20,!go1.27

/*
* Copyright 2022 ByteDance Inc.
Expand Down
64 changes: 33 additions & 31 deletions internal/monkey/inst/generic_extra.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,46 +20,42 @@ import (
_ "unsafe"
)

//go:linkname duffcopy runtime.duffcopy
func duffcopy()
var (
duffcopy, duffzero func()
duffcopyStart, duffcopyEnd uintptr
duffzeroStart, duffzeroEnd uintptr

//go:linkname duffzero runtime.duffzero
func duffzero()

var duffcopyStart, duffcopyEnd, duffzeroStart, duffzeroEnd uintptr
proxyCallRace = map[uintptr]string{}
)

func init() {
duffcopyStart, duffcopyEnd = calcFnAddrRange("duffcopy", duffcopy)
duffzeroStart, duffzeroEnd = calcFnAddrRange("duffzero", duffzero)
}
initDuffFunc()

// proxyCallRace exclude functions used for race check in unit test
//
// If we use '-race' in test command, golang may use 'racefuncenter' and 'racefuncexit' in generic
// function's proxy, which is toxic for us to find the original generic function implementation.
//
// So we need to exclude them. We simply exclude most of race functions defined in runtime.
var proxyCallRace = map[uintptr]string{}
if duffcopy != nil {
duffcopyStart, duffcopyEnd = calcFnAddrRange("duffcopy", duffcopy)
}
if duffzero != nil {
duffzeroStart, duffzeroEnd = calcFnAddrRange("duffzero", duffzero)
}
}

// isGenericProxyCallExtra checks if generic function's proxy called an extra internal function
// We check duffcopy/duffzero for passing huge params/returns and race-functions for -race option
func isGenericProxyCallExtra(addr uintptr) (bool, string) {
/*
When function argument size is too big, golang will use duff-copy
to get better performance. Thus, we will see more call-instruction
in asm code.
For example, assume struct type like this:
```
type Large15 struct _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ string}
```
when we use `Large15` as generic function's argument or return types,
the wrapper `function[Large15]` will call `duffcopy` and `duffzero`
before passing arguments and after receiving returns.
// When function argument size is too big, golang will use duff-copy
// to get better performance. Thus, we will see more call-instruction
// in asm code.
// For example, assume struct type like this:
// ```
// type Large15 struct _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ string}
// ```
// when we use `Large15` as generic function's argument or return types,
// the wrapper `function[Large15]` will call `duffcopy` and `duffzero`
// before passing arguments and after receiving returns.

Notice that `duff` functions are very special, they are always called
in the middle of function body(not at beginning). So we should check
the `call` instruction's target address with a range.
*/
// Notice that `duff` functions are very special, they are always called
// in the middle of function body(not at beginning). So we should check
// the `call` instruction's target address with a range.
if addr >= duffcopyStart && addr <= duffcopyEnd {
return true, "diffcopy"
}
Expand All @@ -68,6 +64,12 @@ func isGenericProxyCallExtra(addr uintptr) (bool, string) {
return true, "duffzero"
}

// proxyCallRace exclude functions used for race check in unit test
//
// If we use '-race' in test command, golang may use 'racefuncenter' and 'racefuncexit' in generic
// function's proxy, which is toxic for us to find the original generic function implementation.
//
// So we need to exclude them. We simply exclude most of race functions defined in runtime.
if name, ok := proxyCallRace[addr]; ok {
return true, name
}
Expand Down
36 changes: 36 additions & 0 deletions internal/monkey/inst/generic_extra_1_26.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//go:build go1.26 && !go1.27
// +build go1.26,!go1.27

/*
* Copyright 2022 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package inst

import (
"reflect"

"github.com/bytedance/mockey/internal/monkey/fn"
"github.com/bytedance/mockey/internal/monkey/linkname"
)

func initDuffFunc() {
if duffcopyPC := linkname.FuncPCForName("runtime.duffcopy"); duffcopyPC > 0 {
duffcopy = fn.MakeFunc(reflect.TypeOf(duffcopy), duffcopyPC).Interface().(func())
}
if duffzeroPC := linkname.FuncPCForName("runtime.duffzero"); duffzeroPC > 0 {
duffzero = fn.MakeFunc(reflect.TypeOf(duffzero), duffzeroPC).Interface().(func())
}
}
35 changes: 35 additions & 0 deletions internal/monkey/inst/generic_extra_below_1_26.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//go:build !go1.26
// +build !go1.26

/*
* Copyright 2022 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package inst

import (
_ "unsafe"
)

func initDuffFunc() {
duffcopy = duffcopy0
duffzero = duffzero0
}

//go:linkname duffcopy0 runtime.duffcopy
func duffcopy0()

//go:linkname duffzero0 runtime.duffzero
func duffzero0()
4 changes: 2 additions & 2 deletions internal/monkey/linkname/linkname.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build !go1.26
// +build !go1.26
//go:build !go1.27
// +build !go1.27

/*
* Copyright 2022 ByteDance Inc.
Expand Down
4 changes: 2 additions & 2 deletions internal/monkey/stw/stw_1_23.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build go1.23 && !go1.26
// +build go1.23,!go1.26
//go:build go1.23 && !go1.27
// +build go1.23,!go1.27

/*
* Copyright 2022 ByteDance Inc.
Expand Down
24 changes: 24 additions & 0 deletions internal/monkey/sysmon/schedt_1_26.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//go:build go1.26 && !go1.27
// +build go1.26,!go1.27

/*
* Copyright 2022 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package sysmon

const (
sysmonLockOffset = 352
)
4 changes: 2 additions & 2 deletions internal/monkey/sysmon/suspend_1_23.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build !mockey_disable_ss && go1.23 && !go1.26
// +build !mockey_disable_ss,go1.23,!go1.26
//go:build !mockey_disable_ss && go1.23 && !go1.27
// +build !mockey_disable_ss,go1.23,!go1.27

/*
* Copyright 2022 ByteDance Inc.
Expand Down
4 changes: 2 additions & 2 deletions internal/monkey/sysmon/suspend_1_23_amd64.s
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build !mockey_disable_ss && go1.23 && !go1.26
// +build !mockey_disable_ss,go1.23,!go1.26
//go:build !mockey_disable_ss && go1.23 && !go1.27
// +build !mockey_disable_ss,go1.23,!go1.27

/*
* Copyright 2022 ByteDance Inc.
Expand Down
4 changes: 2 additions & 2 deletions internal/monkey/sysmon/suspend_1_23_arm64.s
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build !mockey_disable_ss && go1.23 && !go1.26
// +build !mockey_disable_ss,go1.23,!go1.26
//go:build !mockey_disable_ss && go1.23 && !go1.27
// +build !mockey_disable_ss,go1.23,!go1.27

/*
* Copyright 2022 ByteDance Inc.
Expand Down
4 changes: 2 additions & 2 deletions internal/tool/goroutine_1_25.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build go1.25 && !go1.26
// +build go1.25,!go1.26
//go:build go1.25 && !go1.27
// +build go1.25,!go1.27

/*
* Copyright 2022 ByteDance Inc.
Expand Down
4 changes: 2 additions & 2 deletions internal/unsafereflect/name_1_17.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build go1.17 && !go1.26
// +build go1.17,!go1.26
//go:build go1.17 && !go1.27
// +build go1.17,!go1.27

/*
* Copyright 2023 ByteDance Inc.
Expand Down