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:
parent
d9b9980291
commit
fe2497d01e
7 changed files with 128 additions and 2 deletions
2
.github/workflows/push-check-go116.yml
vendored
2
.github/workflows/push-check-go116.yml
vendored
|
|
@ -21,4 +21,4 @@ jobs:
|
||||||
${{ runner.os }}-go-
|
${{ runner.os }}-go-
|
||||||
|
|
||||||
- name: Unit Test
|
- 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 ./...
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,8 @@ var (
|
||||||
modList []*_ModuleData
|
modList []*_ModuleData
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var emptyByte byte
|
||||||
|
|
||||||
func encodeVariant(v int) []byte {
|
func encodeVariant(v int) []byte {
|
||||||
var u int
|
var u int
|
||||||
var r []byte
|
var r []byte
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,8 @@ func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args in
|
||||||
minpc : minpc,
|
minpc : minpc,
|
||||||
maxpc : maxpc,
|
maxpc : maxpc,
|
||||||
modulename : name,
|
modulename : name,
|
||||||
|
gcdata: uintptr(unsafe.Pointer(&emptyByte)),
|
||||||
|
gcbss: uintptr(unsafe.Pointer(&emptyByte)),
|
||||||
}
|
}
|
||||||
|
|
||||||
/* verify and register the new module */
|
/* verify and register the new module */
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,8 @@ func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args in
|
||||||
minpc : minpc,
|
minpc : minpc,
|
||||||
maxpc : maxpc,
|
maxpc : maxpc,
|
||||||
modulename : name,
|
modulename : name,
|
||||||
|
gcdata: uintptr(unsafe.Pointer(&emptyByte)),
|
||||||
|
gcbss: uintptr(unsafe.Pointer(&emptyByte)),
|
||||||
}
|
}
|
||||||
|
|
||||||
/* verify and register the new module */
|
/* verify and register the new module */
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ import (
|
||||||
// This list must match the list in cmd/internal/objabi/funcid.go.
|
// This list must match the list in cmd/internal/objabi/funcid.go.
|
||||||
type funcFlag uint8
|
type funcFlag uint8
|
||||||
|
|
||||||
|
|
||||||
type _Func struct {
|
type _Func struct {
|
||||||
entryOff uint32 // start pc
|
entryOff uint32 // start pc
|
||||||
nameoff int32 // function name
|
nameoff int32 // function name
|
||||||
|
|
@ -186,6 +185,8 @@ func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args in
|
||||||
minpc : minpc,
|
minpc : minpc,
|
||||||
maxpc : maxpc,
|
maxpc : maxpc,
|
||||||
modulename : name,
|
modulename : name,
|
||||||
|
gcdata: uintptr(unsafe.Pointer(&emptyByte)),
|
||||||
|
gcbss: uintptr(unsafe.Pointer(&emptyByte)),
|
||||||
gofunc: base,
|
gofunc: base,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
23
issue_test/plugin/main.go
Normal file
23
issue_test/plugin/main.go
Normal 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
96
issue_test/plugin_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue