GoReplay replays concurrent Go programs semi-deterministically without recording concrete events.
GoReplay injects time.Sleep(time.Duration(hash(seed, context, stack)) % maxInterval)
to arbitrary execution points of the target Go program.
seed
: environmental variableGRSEED
. You can replay the execution by remembering and settingGRSEED
. The default value is empty value and it disables GoReplay.context
: optional[]byte
slice.stack
: runtime stack. (planned)maxInterval
: environmental variableGRMAX
(should betime.Duration
string). The default value is10ms
.
Name | Type | Default | Description |
---|---|---|---|
GRSEED |
string |
(empty) | The seed value for determining the delay. An empty value disables GoReplay. |
GRMAX |
time.Duration |
10ms |
Max delay. |
GRZBIAS |
float64 |
0.0 |
Probability of enforcing the delay to be zero. must be in [0.0, 1.0) . |
Follow the example: example/ex01
.
package main
import (
"fmt"
"sync"
"github.com/AkihiroSuda/go-replay"
)
func main() {
n := 8
var wg sync.WaitGroup
for i := 0; i < n; i++ {
wg.Add(1)
go func(i interface{}) {
msg := fmt.Sprintf("i=%d", i)
replay.Inject([]byte(msg))
fmt.Printf("%s\n", msg)
wg.Done()
}(i)
}
wg.Wait()
}
The result is non-deterministic without GoReplay:
$ go run example/ex01/main.go
i=7
i=5
i=1
i=6
i=0
i=2
i=3
i=4
$ (for f in $(seq 1 10);do go run example/ex01/main.go | sha512sum -; done) | sort | uniq | wc -l
4
If you set GRSEED
, the result becomes deterministic:
$ (for f in $(seq 1 10);do GRSEED=foo go run example/ex01/main.go | sha512sum -; done) | sort | uniq
7ea818bd9e800609ab8e360688d975189033a9b9277d1ad9c9c96c9013f4ffeb1cf05c16ace9de737dcedaa68bc99162d611ac60b7169a43b4f9b17b1665f121 -
$ (for f in $(seq 1 10);do GRSEED=bar go run example/ex01/main.go | sha512sum -; done) | sort | uniq
fc1c177ebbc58baa7e4960102cf26da25173559de0d7a08e00c37a4512eb0a579fc6b4b70f2c708fe1166a1c0641e8839305d5fe7e26624cabbce2cb8274d963 -
- example/etcd-5155: data race (coreos/etcd#5155)
You may use AspectGo(WIP) for automatic instrumentation.
GoReplay is planned to be merged to Namazu.