From ff558f48064e903570581aa9ca317c0f043ae880 Mon Sep 17 00:00:00 2001 From: xhd2015 Date: Wed, 29 May 2024 14:19:03 +0800 Subject: [PATCH] make --strace and --trap-stdlib persistent --- cmd/xgo/runtime_gen/core/version.go | 4 +- cmd/xgo/runtime_gen/trace/trace.go | 13 +-- cmd/xgo/version.go | 4 +- patch/syntax/syntax.go | 93 ++++++++++++++++---- runtime/core/version.go | 4 +- runtime/test/debug/debug_test.go | 10 +-- runtime/test/hello_world/hello_world_test.go | 7 ++ runtime/trace/trace.go | 13 +-- 8 files changed, 106 insertions(+), 42 deletions(-) create mode 100644 runtime/test/hello_world/hello_world_test.go diff --git a/cmd/xgo/runtime_gen/core/version.go b/cmd/xgo/runtime_gen/core/version.go index 180278e2..ef63577b 100755 --- a/cmd/xgo/runtime_gen/core/version.go +++ b/cmd/xgo/runtime_gen/core/version.go @@ -7,8 +7,8 @@ import ( ) const VERSION = "1.0.37" -const REVISION = "da25b0b8838244b76b23707349c5a2b343abc5d9+1" -const NUMBER = 242 +const REVISION = "f52fb37283a2f6c877d110627da71df63638a916+1" +const NUMBER = 243 // these fields will be filled by compiler const XGO_VERSION = "" diff --git a/cmd/xgo/runtime_gen/trace/trace.go b/cmd/xgo/runtime_gen/trace/trace.go index 4c444522..1b1e28d2 100755 --- a/cmd/xgo/runtime_gen/trace/trace.go +++ b/cmd/xgo/runtime_gen/trace/trace.go @@ -20,17 +20,18 @@ import ( var stackMap sync.Map // uintptr(goroutine) -> *Root var testInfoMapping sync.Map // uintptr(goroutine) -> *testInfo +// persist the --strace flag when invoking xgo test // stack trace options: // // on: automatically collect when test starts and ends -var xgoStackTrace = os.Getenv("XGO_STACK_TRACE") +const __xgo_injected_StraceFlag = "" // options: // -// true: stdlib is by default allowed -// TODO: use compiler inserted flag instead of env -var xgoStdlibTrapDefaultAllow = os.Getenv("XGO_STD_LIB_TRAP_DEFAULT_ALLOW") -var skipStdlibTraceByDefault = xgoStdlibTrapDefaultAllow == "true" +// true: stdlib is by default allowed +const __xgo_injected_StdlibTrapDefaultAllow = "" + +var skipStdlibTraceByDefault = __xgo_injected_StdlibTrapDefaultAllow == "true" type testInfo struct { name string @@ -49,7 +50,7 @@ func init() { name: name, } testInfoMapping.LoadOrStore(key, tInfo) - if xgoStackTrace == "on" { + if __xgo_injected_StraceFlag == "on" { tInfo.onFinish = Begin() } }) diff --git a/cmd/xgo/version.go b/cmd/xgo/version.go index b2f956ee..68e863a6 100644 --- a/cmd/xgo/version.go +++ b/cmd/xgo/version.go @@ -3,8 +3,8 @@ package main import "fmt" const VERSION = "1.0.37" -const REVISION = "da25b0b8838244b76b23707349c5a2b343abc5d9+1" -const NUMBER = 242 +const REVISION = "f52fb37283a2f6c877d110627da71df63638a916+1" +const NUMBER = 243 func getRevision() string { revSuffix := "" diff --git a/patch/syntax/syntax.go b/patch/syntax/syntax.go index 874786ce..07f42e6e 100644 --- a/patch/syntax/syntax.go +++ b/patch/syntax/syntax.go @@ -22,6 +22,12 @@ const XGO_VERSION = "XGO_VERSION" const XGO_REVISION = "XGO_REVISION" const XGO_NUMBER = "XGO_NUMBER" +// --strace +const XGO_STACK_TRACE = "XGO_STACK_TRACE" +const XGO_STD_LIB_TRAP_DEFAULT_ALLOW = "XGO_STD_LIB_TRAP_DEFAULT_ALLOW" +const straceFlagConstName = "__xgo_injected_StraceFlag" +const trapStdlibFlagConstName = "__xgo_injected_StdlibTrapDefaultAllow" + // this link function is considered safe as we do not allow user // to define such one,there will no abuse const XgoLinkGeneratedRegisterFunc = "__xgo_link_generated_register_func" @@ -39,7 +45,7 @@ func init() { func AfterFilesParsed(fileList []*syntax.File, addFile func(name string, r io.Reader) *syntax.File) { debugSyntax(fileList) - patchVersions(fileList) + injectXgoFlags(fileList) fillFuncArgResNames(fileList) registerAndTrapFuncs(fileList, addFile) } @@ -303,11 +309,38 @@ func registerAndTrapFuncs(fileList []*syntax.File, addFile func(name string, r i } } -func patchVersions(fileList []*syntax.File) { +func injectXgoFlags(fileList []*syntax.File) { pkgPath := xgo_ctxt.GetPkgPath() - if pkgPath != xgo_ctxt.XgoRuntimeCorePkg { - return + switch pkgPath { + case xgo_ctxt.XgoRuntimeCorePkg: + patchXgoRuntimeCoreVersions(fileList) + case xgo_ctxt.XgoRuntimeTracePkg: + injectXgoStraceFlag(fileList) + } +} + +func findFile(fileList []*syntax.File, name string) *syntax.File { + n := len(name) + for _, file := range fileList { + relFileName := file.Pos().RelFilename() + if !strings.HasSuffix(relFileName, name) { + continue + } + fn := len(relFileName) + if fn == n { + return file + } + c := relFileName[fn-n-1] + + // must be a separator + if c == '/' || c == '\\' || c == filepath.Separator { + return file + } } + return nil +} + +func patchXgoRuntimeCoreVersions(fileList []*syntax.File) { version := os.Getenv(XGO_TOOLCHAIN_VERSION) if version == "" { return @@ -322,22 +355,11 @@ func patchVersions(fileList []*syntax.File) { return } - var versionFile *syntax.File - for _, file := range fileList { - if strings.HasSuffix(file.Pos().RelFilename(), "version.go") { - versionFile = file - break - } - } + versionFile := findFile(fileList, "version.go") if versionFile == nil { return } - for _, decl := range versionFile.DeclList { - constDecl, ok := decl.(*syntax.ConstDecl) - if !ok { - continue - } - + forEachConst(versionFile.DeclList, func(constDecl *syntax.ConstDecl) bool { for _, name := range constDecl.NameList { switch name.Value { case XGO_VERSION: @@ -348,7 +370,44 @@ func patchVersions(fileList []*syntax.File) { constDecl.Values = newIntLit(int(versionNum)) } } + return false + }) +} +func forEachConst(declList []syntax.Decl, fn func(constDecl *syntax.ConstDecl) bool) { + for _, decl := range declList { + constDecl, ok := decl.(*syntax.ConstDecl) + if !ok { + continue + } + if fn(constDecl) { + return + } + } +} + +func injectXgoStraceFlag(fileList []*syntax.File) { + straceFlag := os.Getenv(XGO_STACK_TRACE) + trapStdlibFlag := os.Getenv(XGO_STD_LIB_TRAP_DEFAULT_ALLOW) + if straceFlag == "" && trapStdlibFlag == "" { + return + } + + traceFile := findFile(fileList, "trace.go") + if traceFile == nil { + return } + + forEachConst(traceFile.DeclList, func(constDecl *syntax.ConstDecl) bool { + for _, name := range constDecl.NameList { + switch name.Value { + case straceFlagConstName: + constDecl.Values = newStringLit(straceFlag) + case trapStdlibFlagConstName: + constDecl.Values = newStringLit(trapStdlibFlag) + } + } + return false + }) } func getFileIndexMapping(files []*syntax.File) map[*syntax.File]int { diff --git a/runtime/core/version.go b/runtime/core/version.go index 180278e2..ef63577b 100644 --- a/runtime/core/version.go +++ b/runtime/core/version.go @@ -7,8 +7,8 @@ import ( ) const VERSION = "1.0.37" -const REVISION = "da25b0b8838244b76b23707349c5a2b343abc5d9+1" -const NUMBER = 242 +const REVISION = "f52fb37283a2f6c877d110627da71df63638a916+1" +const NUMBER = 243 // these fields will be filled by compiler const XGO_VERSION = "" diff --git a/runtime/test/debug/debug_test.go b/runtime/test/debug/debug_test.go index 63d9f2c9..56541598 100644 --- a/runtime/test/debug/debug_test.go +++ b/runtime/test/debug/debug_test.go @@ -5,12 +5,8 @@ package debug -const DefaultDateLayout = "2006-01-02 15:04:05.000Z" +import "testing" -func chainedConst() { - wrap(DefaultDateLayout).Min(nil) -} - -func wrap(e string) interface{ Min(t interface{}) } { - return nil +func TestHello(t *testing.T) { + t.Logf("hello world!") } diff --git a/runtime/test/hello_world/hello_world_test.go b/runtime/test/hello_world/hello_world_test.go new file mode 100644 index 00000000..1b7397c2 --- /dev/null +++ b/runtime/test/hello_world/hello_world_test.go @@ -0,0 +1,7 @@ +package main + +import "testing" + +func TestHello(t *testing.T) { + t.Logf("hello world!") +} diff --git a/runtime/trace/trace.go b/runtime/trace/trace.go index 4c444522..1b1e28d2 100644 --- a/runtime/trace/trace.go +++ b/runtime/trace/trace.go @@ -20,17 +20,18 @@ import ( var stackMap sync.Map // uintptr(goroutine) -> *Root var testInfoMapping sync.Map // uintptr(goroutine) -> *testInfo +// persist the --strace flag when invoking xgo test // stack trace options: // // on: automatically collect when test starts and ends -var xgoStackTrace = os.Getenv("XGO_STACK_TRACE") +const __xgo_injected_StraceFlag = "" // options: // -// true: stdlib is by default allowed -// TODO: use compiler inserted flag instead of env -var xgoStdlibTrapDefaultAllow = os.Getenv("XGO_STD_LIB_TRAP_DEFAULT_ALLOW") -var skipStdlibTraceByDefault = xgoStdlibTrapDefaultAllow == "true" +// true: stdlib is by default allowed +const __xgo_injected_StdlibTrapDefaultAllow = "" + +var skipStdlibTraceByDefault = __xgo_injected_StdlibTrapDefaultAllow == "true" type testInfo struct { name string @@ -49,7 +50,7 @@ func init() { name: name, } testInfoMapping.LoadOrStore(key, tInfo) - if xgoStackTrace == "on" { + if __xgo_injected_StraceFlag == "on" { tInfo.onFinish = Begin() } })