Skip to content
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

test --trap-stdlib with kubernetes #161

Closed
wants to merge 2 commits into from
Closed
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
8 changes: 4 additions & 4 deletions .github/workflows/nightly-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
run: |
source util.sh
cd gin-gonic/gin
xgo test -v ./...
xgo test --trap-stdlib -v ./...

- uses: actions/checkout@v4
with:
Expand All @@ -83,7 +83,7 @@ jobs:
run: |
source util.sh
cd pocketbase/pocketbase
xgo test -v ./...
xgo test --trap-stdlib -v ./...

- uses: actions/checkout@v4
with:
Expand All @@ -95,7 +95,7 @@ jobs:
run: |
source util.sh
cd gohugoio/hugo
xgo test -v ./...
xgo test --trap-stdlib -v ./...

- uses: actions/checkout@v4
with:
Expand All @@ -107,7 +107,7 @@ jobs:
run: |
source util.sh
cd kubernetes/kubernetes
xgo test -v ./...
xgo test --trap-stdlib -v ./...

- name: Summary
run: |
Expand Down
7 changes: 4 additions & 3 deletions cmd/xgo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,21 +299,22 @@ func handleBuild(cmd string, args []string) error {
return err
}
}
if isDevelopment || resetInstrument || revisionChanged {
resetOrRevisionChanged := resetInstrument || revisionChanged
if isDevelopment || resetOrRevisionChanged {
logDebug("sync goroot %s -> %s", goroot, instrumentGoroot)
err = syncGoroot(goroot, instrumentGoroot, fullSyncRecord)
if err != nil {
return err
}
// patch go runtime and compiler
logDebug("patch compiler at: %s", instrumentGoroot)
err = patchRuntimeAndCompiler(goroot, instrumentGoroot, realXgoSrc, goVersion, syncWithLink || setupDev || buildCompiler, revisionChanged)
err = patchRuntimeAndCompiler(goroot, instrumentGoroot, realXgoSrc, goVersion, syncWithLink || setupDev || buildCompiler, resetOrRevisionChanged)
if err != nil {
return err
}
}

if resetInstrument || revisionChanged {
if resetOrRevisionChanged {
logDebug("revision %s write to %s", revision, revisionFile)
err := os.WriteFile(revisionFile, []byte(revision), 0755)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions cmd/xgo/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ func init() {
// assume go 1.20
// the patch should be idempotent
// the origGoroot is used to generate runtime defs, see https://github.com/xhd2015/xgo/issues/4#issuecomment-2017880791
func patchRuntimeAndCompiler(origGoroot string, goroot string, xgoSrc string, goVersion *goinfo.GoVersion, syncWithLink bool, revisionChanged bool) error {
func patchRuntimeAndCompiler(origGoroot string, goroot string, xgoSrc string, goVersion *goinfo.GoVersion, syncWithLink bool, resetOrRevisionChanged bool) error {
if goroot == "" {
return fmt.Errorf("requires goroot")
}
if isDevelopment && xgoSrc == "" {
return fmt.Errorf("requires xgoSrc")
}
if !isDevelopment && !revisionChanged {
if !isDevelopment && !resetOrRevisionChanged {
return nil
}

Expand All @@ -58,7 +58,7 @@ func patchRuntimeAndCompiler(origGoroot string, goroot string, xgoSrc string, go
}

// compiler
err = patchCompiler(origGoroot, goroot, goVersion, xgoSrc, revisionChanged, syncWithLink)
err = patchCompiler(origGoroot, goroot, goVersion, xgoSrc, resetOrRevisionChanged, syncWithLink)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/xgo/runtime_gen/core/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
)

const VERSION = "1.0.37"
const REVISION = "f52fb37283a2f6c877d110627da71df63638a916+1"
const NUMBER = 243
const REVISION = "8663e050aab31ade5fb04767b355cbdd830fd926+1"
const NUMBER = 245

// these fields will be filled by compiler
const XGO_VERSION = ""
Expand Down
4 changes: 2 additions & 2 deletions cmd/xgo/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package main
import "fmt"

const VERSION = "1.0.37"
const REVISION = "f52fb37283a2f6c877d110627da71df63638a916+1"
const NUMBER = 243
const REVISION = "8663e050aab31ade5fb04767b355cbdd830fd926+1"
const NUMBER = 245

func getRevision() string {
revSuffix := ""
Expand Down
27 changes: 26 additions & 1 deletion patch/syntax/rewrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func replaceIdent(root syntax.Node, match string, to string) {
})
}

func rewriteStdAndGenericFuncs(funcDecls []*DeclInfo, pkgPath string) {
func rewriteFuncsSource(funcDecls []*DeclInfo, pkgPath string) {
for _, fn := range funcDecls {
if !fn.Kind.IsFunc() {
continue
Expand All @@ -119,6 +119,13 @@ func rewriteStdAndGenericFuncs(funcDecls []*DeclInfo, pkgPath string) {
fnDecl := fn.FuncDecl
pos := fn.FuncDecl.Pos()

// check if body contains recover(), if so
// do not add interceptor
// see https://github.com/xhd2015/xgo/issues/164
if hasRecoverCall(fnDecl.Body) {
continue
}

fnName := fnDecl.Name.Value

// dump
Expand All @@ -136,6 +143,7 @@ func rewriteStdAndGenericFuncs(funcDecls []*DeclInfo, pkgPath string) {
// cannot trap
continue
}

// stop if __xgo_link_generated_trap conflict with recv?
preset[XgoLinkTrapForGenerated] = true

Expand Down Expand Up @@ -414,6 +422,23 @@ func getPresetNames(node syntax.Node) map[string]bool {
return preset
}

func hasRecoverCall(node syntax.Node) bool {
var found bool
syntax.Inspect(node, func(n syntax.Node) bool {
if n == nil {
return false
}
if call, ok := n.(*syntax.CallExpr); ok {
if idt, ok := call.Fun.(*syntax.Name); ok && idt.Value == "recover" {
found = true
return false
}
}
return true
})
return found
}

func copyFuncDeclWithoutBody(decl *syntax.FuncDecl) *syntax.FuncDecl {
return copyFuncDecl(decl, false)
}
Expand Down
5 changes: 3 additions & 2 deletions patch/syntax/syntax.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,9 @@ func registerAndTrapFuncs(fileList []*syntax.File, addFile func(name string, r i
// assign to global
allDecls = funcDelcs

// std lib functions
rewriteStdAndGenericFuncs(funcDelcs, pkgPath)
// std lib, and generic functions
// normal functions uses IR
rewriteFuncsSource(funcDelcs, pkgPath)

if varTrap {
trapVariables(pkgPath, fileList, funcDelcs)
Expand Down
4 changes: 2 additions & 2 deletions runtime/core/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
)

const VERSION = "1.0.37"
const REVISION = "f52fb37283a2f6c877d110627da71df63638a916+1"
const NUMBER = 243
const REVISION = "8663e050aab31ade5fb04767b355cbdd830fd926+1"
const NUMBER = 245

// these fields will be filled by compiler
const XGO_VERSION = ""
Expand Down
10 changes: 10 additions & 0 deletions runtime/test/recover_no_trap/recover_no_trap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package recover_no_trap

func A() {
defer B()
}

func B() string {
recover()
return "B"
}
59 changes: 59 additions & 0 deletions runtime/test/recover_no_trap/recover_no_trap_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package recover_no_trap

import (
"context"
"testing"
"text/template"

"github.com/xhd2015/xgo/runtime/core"
"github.com/xhd2015/xgo/runtime/mock"
)

// bug see https://github.com/xhd2015/xgo/issues/164
// flags: --trap-stdlib
func TestRecoverInStdlibShouldCapturePanic(t *testing.T) {
// if the implementation is right, no panic should happen
txt := `test {{define "content"}}`

_, err := template.New("").Parse(txt)
expectMsg := "template: :1: unexpected EOF"
if err == nil || err.Error() != expectMsg {
t.Fatalf("expect parse err: %q, actual: %q", expectMsg, err.Error())
}
}

func TestRecoverInNonStdlibShouldBeTrapped(t *testing.T) {
var haveMockedA bool
mock.Mock(A, func(ctx context.Context, fn *core.FuncInfo, args, results core.Object) error {
haveMockedA = true
return nil
})
A()
if !haveMockedA {
t.Fatalf("expect have mocked A, actually not")
}

var mockBSetupErr interface{}
var haveMockedB bool
var result string
func() {
defer func() {
mockBSetupErr = recover()
}()
mock.Mock(B, func(ctx context.Context, fn *core.FuncInfo, args, results core.Object) error {
haveMockedB = true
return nil
})
result = B()
}()

if mockBSetupErr != nil {
t.Fatalf("expect setup mock B no error, actual: %v", mockBSetupErr)
}
if !haveMockedB {
t.Fatalf("expect haveMockedB to be true, actual: false")
}
if result != "" {
t.Fatalf("expect B() returns mocked empty string, actual: %v", result)
}
}
6 changes: 6 additions & 0 deletions script/run-test/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ var extraSubTests = []*TestCase{
dir: "runtime/test/bugs/...",
flags: []string{},
},
{
// see https://github.com/xhd2015/xgo/issues/164
name: "stdlib_recover_no_trap",
dir: "runtime/test/recover_no_trap",
flags: []string{"--trap-stdlib"},
},
}

func main() {
Expand Down
Loading