Skip to content

Commit 9fe05ea

Browse files
committed
allow main module snapshot trace by default
1 parent 38209d9 commit 9fe05ea

File tree

13 files changed

+164
-14
lines changed

13 files changed

+164
-14
lines changed

cmd/xgo/exec_tool/debug.go

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func getDebugEnvList(xgoCompilerEnableEnv string) [][2]string {
5050
// strace
5151
{XGO_STACK_TRACE, os.Getenv(XGO_STACK_TRACE)},
5252
{XGO_STACK_TRACE_DIR, os.Getenv(XGO_STACK_TRACE_DIR)},
53+
{XGO_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT, os.Getenv(XGO_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT)},
5354

5455
{XGO_STD_LIB_TRAP_DEFAULT_ALLOW, os.Getenv(XGO_STD_LIB_TRAP_DEFAULT_ALLOW)},
5556
{XGO_DEBUG_COMPILE_PKG, os.Getenv(XGO_DEBUG_COMPILE_PKG)},

cmd/xgo/exec_tool/env.go

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ const XGO_STACK_TRACE = "XGO_STACK_TRACE"
2020
// --strace-dir
2121
const XGO_STACK_TRACE_DIR = "XGO_STACK_TRACE_DIR"
2222

23+
// --strace-snapshot-main-module-default
24+
const XGO_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT = "XGO_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT"
25+
2326
const XGO_COMPILE_PKG_DATA_DIR = "XGO_COMPILE_PKG_DATA_DIR"
2427

2528
const XGO_STD_LIB_TRAP_DEFAULT_ALLOW = "XGO_STD_LIB_TRAP_DEFAULT_ALLOW"

cmd/xgo/main.go

+6
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ func handleBuild(cmd string, args []string) error {
168168
dumpAST := opts.dumpAST
169169
stackTrace := opts.stackTrace
170170
stackTraceDir := opts.stackTraceDir
171+
straceSnapshotMainModuleDefault := opts.straceSnapshotMainModuleDefault
171172
trapStdlib := opts.trapStdlib
172173

173174
if cmdExec && len(remainArgs) == 0 {
@@ -293,7 +294,9 @@ func handleBuild(cmd string, args []string) error {
293294
h.Write(optionsFromFileContent)
294295
buildCacheSuffix += "-" + hex.EncodeToString(h.Sum(nil))
295296
}
297+
var enableStackTrace bool
296298
if stackTrace == "on" || stackTrace == "true" {
299+
enableStackTrace = true
297300
v := stackTrace
298301
if v == "true" {
299302
v = "on"
@@ -660,6 +663,9 @@ func handleBuild(cmd string, args []string) error {
660663
if stackTraceDir != "" {
661664
execCmd.Env = append(execCmd.Env, exec_tool.XGO_STACK_TRACE_DIR+"="+stackTraceDir)
662665
}
666+
if enableStackTrace && straceSnapshotMainModuleDefault != "" {
667+
execCmd.Env = append(execCmd.Env, exec_tool.XGO_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT+"="+straceSnapshotMainModuleDefault)
668+
}
663669

664670
// trap stdlib
665671
var trapStdlibEnv string

cmd/xgo/option.go

+16-7
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ type options struct {
7777
stackTrace string
7878
// --strace-dir
7979
stackTraceDir string
80+
// --strace-snapshot-main-module-default
81+
straceSnapshotMainModuleDefault string
8082

8183
remainArgs []string
8284

@@ -129,6 +131,7 @@ func parseOptions(cmd string, args []string) (*options, error) {
129131
var modfile string
130132
var stackTrace string
131133
var stackTraceDir string
134+
var straceSnapshotMainModuleDefault string
132135
var trapStdlib bool
133136

134137
var remainArgs []string
@@ -358,6 +361,11 @@ func parseOptions(cmd string, args []string) (*options, error) {
358361
stackTrace = argVal
359362
continue
360363
}
364+
stackTraceMainModuleDefaultFlag, val := flag.TrySingleFlag([]string{"--strace-snapshot-main-module-default"}, arg)
365+
if stackTraceMainModuleDefaultFlag != "" {
366+
straceSnapshotMainModuleDefault = val
367+
continue
368+
}
361369

362370
// supported flag: --trap-stdlib, --trap-stdlib=false, --trap-stdlib=true
363371
trapStdlibFlag, trapStdlibVal := flag.TrySingleFlag([]string{"--trap-stdlib"}, arg)
@@ -458,13 +466,14 @@ func parseOptions(cmd string, args []string) (*options, error) {
458466
// default true
459467
syncWithLink: syncWithLink == nil || *syncWithLink,
460468

461-
mod: mod,
462-
gcflags: gcflags,
463-
overlay: overlay,
464-
modfile: modfile,
465-
stackTrace: stackTrace,
466-
stackTraceDir: stackTraceDir,
467-
trapStdlib: trapStdlib,
469+
mod: mod,
470+
gcflags: gcflags,
471+
overlay: overlay,
472+
modfile: modfile,
473+
stackTrace: stackTrace,
474+
stackTraceDir: stackTraceDir,
475+
straceSnapshotMainModuleDefault: straceSnapshotMainModuleDefault,
476+
trapStdlib: trapStdlib,
468477

469478
remainArgs: remainArgs,
470479
testArgs: testArgs,

cmd/xgo/runtime_gen/trace/trace.go

+22
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"fmt"
66
"os"
77
"path/filepath"
8+
"runtime/debug"
89
"strconv"
10+
"strings"
911
"sync"
1012
"testing"
1113
"time"
@@ -27,7 +29,18 @@ type testInfo struct {
2729
onFinish func()
2830
}
2931

32+
var effectMainModule string
33+
3034
func init() {
35+
if flags.MAIN_MODULE != "" {
36+
// fmt.Fprintf(os.Stderr, "DEBUG main module from flags: %s\n", flags.MAIN_MODULE)
37+
effectMainModule = flags.MAIN_MODULE
38+
} else {
39+
buildInfo, _ := debug.ReadBuildInfo()
40+
if buildInfo != nil {
41+
effectMainModule = buildInfo.Main.Path
42+
}
43+
}
3144
__xgo_link_on_test_start(func(t *testing.T, fn func(t *testing.T)) {
3245
name := t.Name()
3346
if name == "" {
@@ -268,6 +281,15 @@ func handleTracePre(ctx context.Context, f *core.FuncInfo, args core.Object, res
268281
break
269282
}
270283
}
284+
285+
// check if allow main module to be defaultly snapshoted
286+
if !anySnapshot && flags.STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT != "false" && effectMainModule != "" && strings.HasPrefix(f.Pkg, effectMainModule) {
287+
// main_module or main_module/*
288+
if len(f.Pkg) == len(effectMainModule) || f.Pkg[len(effectMainModule)] == '/' {
289+
// fmt.Fprintf(os.Stderr, "DEBUG main module snapshot: %s of %s\n", f.Pkg, effectMainModule)
290+
anySnapshot = true
291+
}
292+
}
271293
if anySnapshot {
272294
stack.Snapshot = true
273295
stack.Args = premarshal(stack.Args)

cmd/xgo/runtime_gen/trap/flags/flags.go

+27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
package flags
22

3+
// to inject these flags, see patch/syntax/syntax.go, search for flag_MAIN_MODULE
4+
// this package exists to make flags passed to xgo to be persisted in building and running.
5+
6+
// flag: none
7+
// env: XGO_MAIN_MODULE
8+
// description:
9+
//
10+
// auto detected by xgo in the beginning of building.
11+
// can be used prior to ask runtime/debug's info:
12+
// var mainModulePath = runtime/debug.ReadBuildInfo().Main.Path
13+
const MAIN_MODULE = ""
14+
315
// flag: --strace
416
// env: XGO_STACK_TRACE
517
// description:
@@ -21,6 +33,21 @@ const STRACE = ""
2133
// directory, default current dir
2234
const STRACE_DIR = ""
2335

36+
// flag: --strace-snapshot-main-module
37+
// env: XGO_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT
38+
// description:
39+
//
40+
// collecting main module's trace in snapshot mode,
41+
// while other's are non snapshot mode
42+
//
43+
// snapshot mode: args are serialized before executing
44+
// the function, and results are serilaized after return.
45+
// this is useful if an object will be modified in later
46+
// process.
47+
//
48+
// values: true or false
49+
const STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT = ""
50+
2451
// flag: --trap-stdlib
2552
// env: XGO_STD_LIB_TRAP_DEFAULT_ALLOW
2653
// description: if true, stdlib trap is by default allowed

cmd/xgo/trace.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ type importResult struct {
2929
var runtimeGenFS embed.FS
3030

3131
// TODO: may apply tags
32+
// importRuntimeDep detect if the target package already
33+
// has github.com/xhd2015/xgo/runtime as dependency,
34+
// if not, dynamically modify the go.mod to include that,
35+
// and add a blank import in the main package
3236
func importRuntimeDep(test bool, goroot string, goBinary string, goVersion *goinfo.GoVersion, absModFile string, xgoSrc string, projectDir string, modRootRel []string, mainModule string, mod string, args []string) (*importResult, error) {
3337
if mainModule == "" {
3438
// only work with module
@@ -64,7 +68,6 @@ func importRuntimeDep(test bool, goroot string, goBinary string, goVersion *goin
6468
return nil, err
6569
}
6670

67-
pkgArgs := getPkgArgs(args)
6871
tmpRoot, tmpProjectDir, err := createWorkDir(projectRoot)
6972
if err != nil {
7073
return nil, err
@@ -84,6 +87,7 @@ func importRuntimeDep(test bool, goroot string, goBinary string, goVersion *goin
8487
}
8588
}
8689

90+
pkgArgs := getPkgArgs(args)
8791
fileReplace, err := addBlankImports(goroot, goBinary, projectDir, pkgArgs, test, tmpProjectDir)
8892
if err != nil {
8993
return nil, err
@@ -171,8 +175,10 @@ type Overlay struct {
171175

172176
type dependencyInfo struct {
173177
modReplace map[string]string
174-
mod string
175-
modfile string // alternative go.mod
178+
// the -mod flag
179+
mod string
180+
// the -modfile flag
181+
modfile string // alternative go.mod
176182
}
177183

178184
func createWorkDir(projectRoot string) (tmpRoot string, tmpProjectDir string, err error) {

cmd/xgo/version.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import "fmt"
66
// VERSION is manually updated when needed a new tag
77
// see also runtime/core/version.go
88
const VERSION = "1.0.51"
9-
const REVISION = "f43d1801162be8396dd5b73a27b529253a121a88+1"
10-
const NUMBER = 319
9+
const REVISION = "38209d904dbe681a458641ad5e7f1c408c8a3626+1"
10+
const NUMBER = 320
1111

1212
// the matching runtime/core's version
1313
// manually updated

doc/test-explorer/README.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ An example config:
2020
"env":{
2121
"TEST_WITH_XGO":"true"
2222
},
23-
"flags":["-p=12"],
23+
"flags":["-p=4"],
2424
"args":["--my-program-env","TEST"],
2525
"mock_rules":[{
2626
"stdlib": true,
@@ -149,10 +149,17 @@ Definition:
149149
Definition:
150150
```json
151151
{
152-
"disabled": true
152+
"disabled": true|false,
153+
"diff_with": "origin/master",
154+
"include": [...],
155+
"exclude": [...]
153156
}
154157
```
155158

156159
By default, if `coverage` is missing or `null`, then coverage is enabled.
157160

161+
If set `diff_with` to `none`, then incremental coverage will be disabled.
162+
163+
`include` and `exclude` specify which files will be included or excluded in coverage display.
164+
158165
Setting `"coverage": false` or `"coverage":{"disabled": true}` will disable it.

patch/syntax/syntax.go

+11
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,27 @@ const XGO_VERSION = "XGO_VERSION"
3030
const XGO_REVISION = "XGO_REVISION"
3131
const XGO_NUMBER = "XGO_NUMBER"
3232

33+
const XGO_MAIN_MODULE = "XGO_MAIN_MODULE"
34+
3335
// --strace
3436
const XGO_STACK_TRACE = "XGO_STACK_TRACE"
3537
const XGO_STACK_TRACE_DIR = "XGO_STACK_TRACE_DIR"
38+
const XGO_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT = "XGO_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT"
3639
const XGO_STD_LIB_TRAP_DEFAULT_ALLOW = "XGO_STD_LIB_TRAP_DEFAULT_ALLOW"
3740

3841
// Deprecated: use flag_STRACE,.. instead
3942
const straceFlagConstName = "__xgo_injected_StraceFlag"
4043
const trapStdlibFlagConstName = "__xgo_injected_StdlibTrapDefaultAllow"
4144

4245
const (
46+
// auto detected
47+
flag_MAIN_MODULE = "MAIN_MODULE"
4348
// --strace
4449
flag_STRACE = "STRACE"
4550
// --strace-dir
4651
flag_STRACE_DIR = "STRACE_DIR"
52+
// --strace-snapshot-main-module
53+
flag_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT = "STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT"
4754
// --trap-stdlib
4855
flag_TRAP_STDLIB = "TRAP_STDLIB"
4956
)
@@ -454,10 +461,14 @@ func injectXgoGeneralFlags(fileList []*syntax.File) {
454461
forEachConst(file.DeclList, func(constDecl *syntax.ConstDecl) bool {
455462
for _, name := range constDecl.NameList {
456463
switch name.Value {
464+
case flag_MAIN_MODULE:
465+
constDecl.Values = newStringLit(os.Getenv(XGO_MAIN_MODULE))
457466
case flag_STRACE:
458467
constDecl.Values = newStringLit(os.Getenv(XGO_STACK_TRACE))
459468
case flag_STRACE_DIR:
460469
constDecl.Values = newStringLit(os.Getenv(XGO_STACK_TRACE_DIR))
470+
case flag_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT:
471+
constDecl.Values = newStringLit(os.Getenv(XGO_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT))
461472
case flag_TRAP_STDLIB:
462473
constDecl.Values = newStringLit(os.Getenv(XGO_STD_LIB_TRAP_DEFAULT_ALLOW))
463474
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package snapshot_main_default
2+
3+
import "testing"
4+
5+
func TestSnapshotMainDefault(t *testing.T) {
6+
// TODO: I forgot how to write test against trace
7+
// see https://github.com/xhd2015/xgo/issues/281#issuecomment-2466153734
8+
// for test detail
9+
}

runtime/trace/trace.go

+22
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"fmt"
66
"os"
77
"path/filepath"
8+
"runtime/debug"
89
"strconv"
10+
"strings"
911
"sync"
1012
"testing"
1113
"time"
@@ -27,7 +29,18 @@ type testInfo struct {
2729
onFinish func()
2830
}
2931

32+
var effectMainModule string
33+
3034
func init() {
35+
if flags.MAIN_MODULE != "" {
36+
// fmt.Fprintf(os.Stderr, "DEBUG main module from flags: %s\n", flags.MAIN_MODULE)
37+
effectMainModule = flags.MAIN_MODULE
38+
} else {
39+
buildInfo, _ := debug.ReadBuildInfo()
40+
if buildInfo != nil {
41+
effectMainModule = buildInfo.Main.Path
42+
}
43+
}
3144
__xgo_link_on_test_start(func(t *testing.T, fn func(t *testing.T)) {
3245
name := t.Name()
3346
if name == "" {
@@ -268,6 +281,15 @@ func handleTracePre(ctx context.Context, f *core.FuncInfo, args core.Object, res
268281
break
269282
}
270283
}
284+
285+
// check if allow main module to be defaultly snapshoted
286+
if !anySnapshot && flags.STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT != "false" && effectMainModule != "" && strings.HasPrefix(f.Pkg, effectMainModule) {
287+
// main_module or main_module/*
288+
if len(f.Pkg) == len(effectMainModule) || f.Pkg[len(effectMainModule)] == '/' {
289+
// fmt.Fprintf(os.Stderr, "DEBUG main module snapshot: %s of %s\n", f.Pkg, effectMainModule)
290+
anySnapshot = true
291+
}
292+
}
271293
if anySnapshot {
272294
stack.Snapshot = true
273295
stack.Args = premarshal(stack.Args)

runtime/trap/flags/flags.go

+27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
package flags
22

3+
// to inject these flags, see patch/syntax/syntax.go, search for flag_MAIN_MODULE
4+
// this package exists to make flags passed to xgo to be persisted in building and running.
5+
6+
// flag: none
7+
// env: XGO_MAIN_MODULE
8+
// description:
9+
//
10+
// auto detected by xgo in the beginning of building.
11+
// can be used prior to ask runtime/debug's info:
12+
// var mainModulePath = runtime/debug.ReadBuildInfo().Main.Path
13+
const MAIN_MODULE = ""
14+
315
// flag: --strace
416
// env: XGO_STACK_TRACE
517
// description:
@@ -21,6 +33,21 @@ const STRACE = ""
2133
// directory, default current dir
2234
const STRACE_DIR = ""
2335

36+
// flag: --strace-snapshot-main-module
37+
// env: XGO_STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT
38+
// description:
39+
//
40+
// collecting main module's trace in snapshot mode,
41+
// while other's are non snapshot mode
42+
//
43+
// snapshot mode: args are serialized before executing
44+
// the function, and results are serilaized after return.
45+
// this is useful if an object will be modified in later
46+
// process.
47+
//
48+
// values: true or false
49+
const STRACE_SNAPSHOT_MAIN_MODULE_DEFAULT = ""
50+
2451
// flag: --trap-stdlib
2552
// env: XGO_STD_LIB_TRAP_DEFAULT_ALLOW
2653
// description: if true, stdlib trap is by default allowed

0 commit comments

Comments
 (0)