Skip to content

Commit

Permalink
Merge pull request #39 from bytedance/feat/gcflags
Browse files Browse the repository at this point in the history
feat: check inlining and optimization when init mockey
  • Loading branch information
Sychorius authored Oct 9, 2023
2 parents 7eec163 + df5713c commit 7076ba5
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ jobs:
- name: Unit Test
run: MOCKEY_DEBUG=true go test -gcflags="all=-l -N" -covermode=atomic -coverprofile=coverage.out ./...
- name: Benchmark
run: go test -bench=. -benchmem -run=none ./...
run: go test -gcflags="all=-l -N" -bench=. -benchmem -run=none ./...
2 changes: 1 addition & 1 deletion internal/monkey/mem/write_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
func Write(target uintptr, data []byte) error {
targetPage := common.PageOf(target)
fnPage := common.PageOf(reflect.ValueOf(write).Pointer())
tool.DebugPrintf("Write: target page(0x%x), fn page(0x%x)\n", targetPage, fnPage)
tool.DebugPrintf("Write: target page(0x%x), fn page(0x%x), len(%v)\n", targetPage, fnPage, len(data))
res := write(target, common.PtrOf(data), len(data), targetPage, common.PageSize(), syscall.PROT_READ|syscall.PROT_EXEC)
if res != 0 {
return fmt.Errorf("write failed, code %v", res)
Expand Down
2 changes: 1 addition & 1 deletion internal/monkey/mem/write_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
func Write(target uintptr, data []byte) error {
targetPage := common.PageOf(target)
fnPage := common.PageOf(reflect.ValueOf(write).Pointer())
tool.DebugPrintf("Write: target page(0x%x), fn page(0x%x)\n", targetPage, fnPage)
tool.DebugPrintf("Write: target page(0x%x), fn page(0x%x), len(%v)\n", targetPage, fnPage, len(data))
res := write(target, common.PtrOf(data), len(data), targetPage, common.PageSize(), syscall.PROT_READ|syscall.PROT_EXEC)
if res != 0 {
return fmt.Errorf("write failed, code %v", res)
Expand Down
36 changes: 36 additions & 0 deletions internal/tool/check_gcflags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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 tool

import (
"os"
)

func init() {
// set MOCKEY_CHECK_GCFLAGS=false to disable this check
checkGCflags()
}

func checkGCflags() int {
if flag := os.Getenv("MOCKEY_CHECK_GCFLAGS"); flag != "false" && !IsGCFlagsSet() {
panic(`
Mockey init failed, did you forget to add -gcflags="all=-N -l" ?
(Set env MOCKEY_CHECK_GCFLAGS=false to disable gcflags check)
`)
}
return 0
}
54 changes: 54 additions & 0 deletions internal/tool/check_gcflags_amd64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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 tool

import (
"reflect"
"unsafe"

"golang.org/x/arch/x86/x86asm"
)

func fn() {
}

func fn2() {
fn()
}

func IsGCFlagsSet() bool {
var asm []byte
header := (*reflect.SliceHeader)(unsafe.Pointer(&asm))
header.Data = reflect.ValueOf(fn2).Pointer()
header.Len = 1000
header.Cap = 1000

flag := false
pos := 0
for pos < len(asm) {
inst, _ := x86asm.Decode(asm[pos:], 64)
if inst.Op == x86asm.RET {
break
}
if inst.Op == x86asm.CALL {
flag = true
break
}
pos += int(inst.Len)
}
return flag
}
54 changes: 54 additions & 0 deletions internal/tool/check_gcflags_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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 tool

import (
"reflect"
"unsafe"

"golang.org/x/arch/arm64/arm64asm"
)

func fn() {
}

func fn2() {
fn()
}

func IsGCFlagsSet() bool {
var asm []byte
header := (*reflect.SliceHeader)(unsafe.Pointer(&asm))
header.Data = reflect.ValueOf(fn2).Pointer()
header.Len = 1000
header.Cap = 1000

flag := false
pos := 0
for pos < len(asm) {
inst, _ := arm64asm.Decode(asm[pos:])
if inst.Op == arm64asm.RET {
break
}
if inst.Op == arm64asm.BL {
flag = true
break
}
pos += int(unsafe.Sizeof(inst.Enc))
}
return flag
}

0 comments on commit 7076ba5

Please sign in to comment.