2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +08:00

fix:(loader) init _Moduledata.gcdatapointer to avoid panic on plugin-mode (#188)

* fix:(loader) init `_Moduledata.gcdata`pointer to avoid panic on plugin-mode

* fix: freeze gcdata pointer

* feat: go115

* update test

* fix: use unique bytes pointer

* test: drop go1.15 race test

* feat: support go1.18
This commit is contained in:
Yi Duan 2022-04-01 16:46:07 +08:00 committed by GitHub
parent d9b9980291
commit fe2497d01e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 128 additions and 2 deletions

View file

@ -21,4 +21,4 @@ jobs:
${{ runner.os }}-go-
- name: Unit Test
run: GOMAXPROCS=4 go test -v -race -gcflags=-d=checkptr=0 -covermode=atomic -coverprofile=coverage.out ./...
run: GOMAXPROCS=4 go test -v -gcflags=-d=checkptr=0 -race -covermode=atomic -coverprofile=coverage.out ./...

View file

@ -53,6 +53,8 @@ var (
modList []*_ModuleData
)
var emptyByte byte
func encodeVariant(v int) []byte {
var u int
var r []byte

View file

@ -155,6 +155,8 @@ func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args in
minpc : minpc,
maxpc : maxpc,
modulename : name,
gcdata: uintptr(unsafe.Pointer(&emptyByte)),
gcbss: uintptr(unsafe.Pointer(&emptyByte)),
}
/* verify and register the new module */

View file

@ -159,6 +159,8 @@ func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args in
minpc : minpc,
maxpc : maxpc,
modulename : name,
gcdata: uintptr(unsafe.Pointer(&emptyByte)),
gcbss: uintptr(unsafe.Pointer(&emptyByte)),
}
/* verify and register the new module */

View file

@ -28,7 +28,6 @@ import (
// This list must match the list in cmd/internal/objabi/funcid.go.
type funcFlag uint8
type _Func struct {
entryOff uint32 // start pc
nameoff int32 // function name
@ -186,6 +185,8 @@ func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args in
minpc : minpc,
maxpc : maxpc,
modulename : name,
gcdata: uintptr(unsafe.Pointer(&emptyByte)),
gcbss: uintptr(unsafe.Pointer(&emptyByte)),
gofunc: base,
}

23
issue_test/plugin/main.go Normal file
View file

@ -0,0 +1,23 @@
package main
import (
`fmt`
`github.com/bytedance/sonic`
)
var V int
var Obj map[string]string
func init() {
if err := sonic.UnmarshalString(`{"a":"b"}`, &Obj); err != nil {
panic(err)
}
}
func F() { fmt.Printf("Hello, number %d\n", V) }
func Unmarshal(json string, val interface{}) error {
return sonic.UnmarshalString(json, val)
}

96
issue_test/plugin_test.go Normal file
View file

@ -0,0 +1,96 @@
// +build !race
/*
* Copyright 2021 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 issue_test
import (
`bytes`
`fmt`
`os/exec`
`plugin`
`runtime`
`testing`
`reflect`
_ `github.com/bytedance/sonic`
)
func buildPlugin() {
out := bytes.NewBuffer(nil)
bin0, err := exec.LookPath("rm")
if err != nil {
panic(err)
}
cmd0 := exec.Cmd{
Path: bin0,
Args: []string{"rm", "-f", "plugin/plugin."+runtime.Version()+".so"},
Stdout: out,
Stderr: out,
}
if err := cmd0.Run(); err != nil {
panic(string(out.Bytes()))
}
out.Reset()
bin, err := exec.LookPath("go")
if err != nil {
panic(err)
}
cmd := exec.Cmd{
Path: bin,
Args: []string{"go", "build", "-buildmode", "plugin", "-o", "plugin/plugin."+runtime.Version()+".so", "plugin/main.go"},
Stdout: out,
Stderr: out,
}
if err := cmd.Run(); err != nil {
panic(string(out.Bytes()))
}
}
func TestPlugin(t *testing.T) {
buildPlugin()
p, err := plugin.Open("plugin/plugin."+runtime.Version()+".so")
if err != nil {
t.Fatal(err)
}
v, err := p.Lookup("V")
if err != nil {
t.Fatal(err)
}
f, err := p.Lookup("F")
if err != nil {
t.Fatal(err)
}
*v.(*int) = 7
f.(func())() // prints "Hello, number 7"
obj, err := p.Lookup("Obj")
m := *(obj.(*map[string]string))
fmt.Printf("%#v\n", m)
d, err := p.Lookup("Unmarshal")
if err != nil {
t.Fatal(err)
}
dec := d.(func(json string, val interface{}) error)
var exp map[string]string
if err := dec(`{"a":"b"}`, &exp); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(m, exp) {
t.Fatal(m, exp)
}
}