Skip to content

Commit

Permalink
enable trace snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
xhd2015 committed Jul 26, 2024
1 parent ddb79e3 commit 9ef6d20
Show file tree
Hide file tree
Showing 12 changed files with 606 additions and 31 deletions.
9 changes: 7 additions & 2 deletions cmd/xgo/runtime_gen/trace/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ type Stack struct {
Begin int64 // us
End int64 // us

Args core.Object
Results core.Object
Args core.Object
Results core.Object

// is recorded as snapshot
Snapshot bool

Panic bool
Error error
Children []*Stack
Expand Down Expand Up @@ -177,6 +181,7 @@ func (c *Stack) Export(opts *ExportOptions) *StackExport {
End: c.End,
Args: args,
Results: results,
Snapshot: c.Snapshot,
Panic: c.Panic,
Error: errMsg,
Children: ((stacks)(c.Children)).Export(opts),
Expand Down
8 changes: 6 additions & 2 deletions cmd/xgo/runtime_gen/trace/stack_export.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ type StackExport struct {

Args interface{}
Results interface{}
Panic bool
Error string

// is recorded as snapshot
Snapshot bool

Panic bool
Error string

Children []*StackExport
}
Expand Down
79 changes: 70 additions & 9 deletions cmd/xgo/runtime_gen/trace/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,14 @@ type CollectOptions struct {
}

type collectOpts struct {
name string
onComplete func(root *Root)
filter []func(stack *Stack) bool
root *Root
options *CollectOptions
exportOptions *ExportOptions
name string
onComplete func(root *Root)
filters []func(stack *Stack) bool
postFilters []func(stack *Stack)
snapshotFilters []func(stack *Stack) bool
root *Root
options *CollectOptions
exportOptions *ExportOptions
}

func Options() *collectOpts {
Expand All @@ -178,7 +180,17 @@ func (c *collectOpts) OnComplete(f func(root *Root)) *collectOpts {
}

func (c *collectOpts) WithFilter(f func(stack *Stack) bool) *collectOpts {
c.filter = append(c.filter, f)
c.filters = append(c.filters, f)
return c
}

func (c *collectOpts) WithPostFilter(f func(stack *Stack)) *collectOpts {
c.postFilters = append(c.postFilters, f)
return c
}

func (c *collectOpts) WithSnapshot(f func(stack *Stack) bool) *collectOpts {
c.snapshotFilters = append(c.snapshotFilters, f)
return c
}

Expand Down Expand Up @@ -256,10 +268,22 @@ func handleTracePre(ctx context.Context, f *core.FuncInfo, args core.Object, res
initial = true
}
} else {
if !checkFilter(stack, localOpts.filter) {
if !checkFilters(stack, localOpts.filters) {
// do not collect trace if filtered out
return nil, trap.ErrSkip
}
var anySnapshot bool
for _, f := range localOpts.snapshotFilters {
if f(stack) {
anySnapshot = true
break
}
}
if anySnapshot {
stack.Snapshot = true
stack.Args = premarshal(stack.Args)
}

localRoot = localOpts.root
if localRoot == nil {
initial = true
Expand Down Expand Up @@ -305,7 +329,7 @@ func handleTracePre(ctx context.Context, f *core.FuncInfo, args core.Object, res
return prevTop, nil
}

func checkFilter(stack *Stack, filters []func(stack *Stack) bool) bool {
func checkFilters(stack *Stack, filters []func(stack *Stack) bool) bool {
for _, f := range filters {
if !f(stack) {
return false
Expand Down Expand Up @@ -333,13 +357,19 @@ func handleTracePost(ctx context.Context, f *core.FuncInfo, args core.Object, re
panic(fmt.Errorf("unbalanced stack"))
}
root = localOpts.root
for _, f := range localOpts.postFilters {
f(root.Top)
}
} else {
v, ok := stackMap.Load(key)
if !ok {
panic(fmt.Errorf("unbalanced stack"))
}
root = v.(*Root)
}
if root.Top != nil && root.Top.Snapshot {
root.Top.Results = premarshal(root.Top.Results)
}

// detect panic
pe := __xgo_link_peek_panic()
Expand Down Expand Up @@ -543,3 +573,34 @@ func emitTrace(name string, root *Root, opts *ExportOptions) error {
})
return err
}

func premarshal(v core.Object) (res core.Object) {
var err error
var data []byte
defer func() {
if e := recover(); e != nil {
if pe, ok := e.(error); ok {
err = pe
} else {
err = fmt.Errorf("marshal %T: %v", v, e)
}
}
if err != nil {
data = []byte(`{"err":` + strconv.Quote(err.Error()) + ` }`)
}
res = &premarshaled{Object: v, data: data}
}()
data, err = MarshalAnyJSON(v)
return
}

type premarshaled struct {
core.Object
data []byte
}

var _ core.Object = (*premarshaled)(nil)

func (c *premarshaled) MarshalJSON() ([]byte, error) {
return c.data, nil
}
4 changes: 2 additions & 2 deletions cmd/xgo/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import "fmt"

// auto updated
const VERSION = "1.0.46"
const REVISION = "baec4d50e4c26d279fe32cd30c7649d707b8f1ce+1"
const NUMBER = 299
const REVISION = "ddb79e33f33b43c8eb97936e31212bc2f54ac3c1+1"
const NUMBER = 300

// manually updated
const CORE_VERSION = "1.0.43"
Expand Down
6 changes: 3 additions & 3 deletions runtime/test/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ module github.com/xhd2015/xgo/runtime/test

go 1.18

require (
github.com/xhd2015/xgo/runtime v1.0.16
)
require github.com/xhd2015/xgo/runtime v1.0.16

require github.com/xhd2015/xgo v1.0.47-0.20240726085913-ddb79e33f33b

replace github.com/xhd2015/xgo/runtime => ../
2 changes: 2 additions & 0 deletions runtime/test/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/xhd2015/xgo v1.0.47-0.20240726085913-ddb79e33f33b h1:D0+4qUvmlcG2QTi6RU7xBnzemRrLyM7QYnYVd4jhR+g=
github.com/xhd2015/xgo v1.0.47-0.20240726085913-ddb79e33f33b/go.mod h1:LJxlcYSaXo/9YpsnB3yHh9NHe7BRettYCytaNGWY2BE=
37 changes: 37 additions & 0 deletions runtime/test/trace/snapshot/snapshot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package snapshot

type _InOut struct {
Last string
Count int
}

type _Response struct {
Last string
Count int
}

func handleL1() *_Response {
_, resp := handleL2()
resp.Last = "handleL1"
resp.Count++
return resp
}

func handleL2() (*_InOut, *_Response) {
a := &_InOut{
Last: "handleL2",
}
resp := handleL3(a)

resp.Last = "handleL2"
resp.Count++
return a, resp
}

func handleL3(a *_InOut) *_Response {
a.Last = "handleL3"
a.Count++
return &_Response{
Last: "handleL3",
}
}
Loading

0 comments on commit 9ef6d20

Please sign in to comment.