diff --git a/README.md b/README.md
index 7132dc30..6a717fcc 100644
--- a/README.md
+++ b/README.md
@@ -363,13 +363,10 @@ import (
"fmt"
"testing"
- "github.com/xhd2015/xgo/runtime/trace"
+ _ "github.com/xhd2015/xgo/runtime/trace"
)
func TestTrace(t *testing.T) {
- // begin trace
- finish := trace.Begin()
- defer finish()
A()
B()
C()
@@ -385,7 +382,8 @@ Run with `xgo`:
```sh
# run the test
# this will write the trace into TestTrace.json
-xgo test ./
+# --strace represents stack trace
+xgo test --strace ./
# view the trace
xgo tool trace TestTrace.json
@@ -407,6 +405,20 @@ By default, Trace will write traces to a temp directory under current working di
- `XGO_TRACE_OUTPUT=
`: traces will be written to ``,
- `XGO_TRACE_OUTPUT=off`: turn off trace.
+Besides the `--strace` flag, xgo allows you to define which span should be collected, using `trace.Begin()`:
+```go
+import "github.com/xhd2015/xgo/runtime/trace"
+
+func TestTrace(t *testing.T) {
+ A()
+ finish := trace.Begin()
+ defer finish()
+ B()
+ C()
+}
+```
+The trace will only include `B()` and `C()`
+
# Concurrent safety
I know you guys from other monkey patching library suffer from the unsafety implied by these frameworks.
diff --git a/README_zh_cn.md b/README_zh_cn.md
index 50307ac2..1ebc958f 100644
--- a/README_zh_cn.md
+++ b/README_zh_cn.md
@@ -354,13 +354,10 @@ import (
"fmt"
"testing"
- "github.com/xhd2015/xgo/runtime/trace"
+ _ "github.com/xhd2015/xgo/runtime/trace"
)
func TestTrace(t *testing.T) {
- // begin trace
- finish := trace.Begin()
- defer finish()
A()
B()
C()
@@ -397,6 +394,20 @@ xgo tool trace TestTrace.json
- `XGO_TRACE_OUTPUT=`: 堆栈记录被写入到``目录下,
- `XGO_TRACE_OUTPUT=off`: 关闭堆栈记录收集。
+除了使用`--strace`之外, xgo还允许你通过`trace.Begin()`的方式手动控制追踪范围:
+```go
+import "github.com/xhd2015/xgo/runtime/trace"
+
+func TestTrace(t *testing.T) {
+ A()
+ finish := trace.Begin()
+ defer finish()
+ B()
+ C()
+}
+```
+结果中只会包含`B()`和`C()`.
+
# 并发安全
我知道大部分人认为Monkey Patching不是并发安全的,但那是现有的库的实现方式决定的。
diff --git a/cmd/xgo/version.go b/cmd/xgo/version.go
index d8d9e221..b809324c 100644
--- a/cmd/xgo/version.go
+++ b/cmd/xgo/version.go
@@ -3,8 +3,8 @@ package main
import "fmt"
const VERSION = "1.0.25"
-const REVISION = "6eeff524a454a6032a2294b47d1dc1c892b5545f+1"
-const NUMBER = 186
+const REVISION = "ae8695c56e8c7f1976d409c7fba953041983c299+1"
+const NUMBER = 187
func getRevision() string {
revSuffix := ""
diff --git a/runtime/core/version.go b/runtime/core/version.go
index 98a35b5a..61342fab 100644
--- a/runtime/core/version.go
+++ b/runtime/core/version.go
@@ -7,8 +7,8 @@ import (
)
const VERSION = "1.0.25"
-const REVISION = "6eeff524a454a6032a2294b47d1dc1c892b5545f+1"
-const NUMBER = 186
+const REVISION = "ae8695c56e8c7f1976d409c7fba953041983c299+1"
+const NUMBER = 187
// these fields will be filled by compiler
const XGO_VERSION = ""
diff --git a/runtime/trap/interceptor.go b/runtime/trap/interceptor.go
index 4342d45e..1da4a75a 100644
--- a/runtime/trap/interceptor.go
+++ b/runtime/trap/interceptor.go
@@ -126,6 +126,24 @@ type interceptorManager struct {
funcMapping map[*core.FuncInfo][]*Interceptor // nested mapping
}
+func (c *interceptorManager) hasAny() bool {
+ if c == nil {
+ return false
+ }
+ if len(c.head) > 0 {
+ return true
+ }
+ if len(c.tail) > 0 {
+ return true
+ }
+ for _, m := range c.funcMapping {
+ if len(m) > 0 {
+ return true
+ }
+ }
+ return false
+}
+
func (c *interceptorManager) copy() *interceptorManager {
if c == nil {
return nil
diff --git a/runtime/trap/trap.go b/runtime/trap/trap.go
index 85b973e6..b9a7b847 100644
--- a/runtime/trap/trap.go
+++ b/runtime/trap/trap.go
@@ -38,7 +38,7 @@ func init() {
return
}
local := getLocalInterceptorList()
- if local == nil || (len(local.head) == 0 && len(local.tail) == 0) {
+ if !local.hasAny() {
return
}
// inherit interceptors of last group