diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2021-12-01 17:53:13 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2021-12-10 12:30:07 +0100 |
| commit | 15439f1624735bde5ae3f3b66c1b964a980415b3 (patch) | |
| tree | 4e9aacba8e41b511f8fb8c60d09d5c4b1c98287d /prog/collide.go | |
| parent | 18f846ca807cfc6df9c3da3c0ab08251277dfefb (diff) | |
all: add the `DoubleExecCollide` strategy
Add a strategy that resembles the previous collide mode, but detaches not
every other call, rather all calls during the second execution (or at least
as much as possible). Follow the strategy for 33% of all collide
executions.
It was shown during the experiments that this strategy has a positive
effect on the number of discovered crashes and bugs.
Diffstat (limited to 'prog/collide.go')
| -rw-r--r-- | prog/collide.go | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/prog/collide.go b/prog/collide.go index 77065147f..fea8cc146 100644 --- a/prog/collide.go +++ b/prog/collide.go @@ -5,7 +5,10 @@ package prog -import "math/rand" +import ( + "fmt" + "math/rand" +) // The executor has no more than 32 threads that are used both for async calls and for calls // that timed out. If we just ignore that limit, we could end up generating programs that @@ -71,3 +74,26 @@ func AssignRandomRerun(prog *Prog, rand *rand.Rand) { i++ } } + +// We append prog to itself, but let the second part only reference resource from the first one. +// Then we execute all the duplicated calls simultaneously. +// This somehow resembles the way the previous collide mode was implemented - a program was executed +// normally and then one more time again, while keeping resource values from the first execution and +// not waiting until every other call finishes. +func DoubleExecCollide(origProg *Prog, rand *rand.Rand) (*Prog, error) { + if len(origProg.Calls)*2 > MaxCalls { + return nil, fmt.Errorf("the prog is too big for the DoubleExecCollide transformation") + } + prog := origProg.Clone() + dupCalls := cloneCalls(prog.Calls, nil) + leftAsync := maxAsyncPerProg + for _, c := range dupCalls { + if leftAsync == 0 { + break + } + c.Props.Async = true + leftAsync-- + } + prog.Calls = append(prog.Calls, dupCalls...) + return prog, nil +} |
