GoPLS Viewer

Home|gopls/cmd/signature-fuzzer/internal/fuzz-generator/wraprand.go
1// Copyright 2021 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package generator
6
7import (
8    "fmt"
9    "math/rand"
10    "os"
11    "runtime"
12    "strings"
13)
14
15const (
16    RandCtlNochecks = 0
17    RandCtlChecks   = 1 << iota
18    RandCtlCapture
19    RandCtlPanic
20)
21
22func NewWrapRand(seed int64ctl int) *wraprand {
23    rand.Seed(seed)
24    return &wraprand{seedseedctlctl}
25}
26
27type wraprand struct {
28    f32calls  int
29    f64calls  int
30    intncalls int
31    seed      int64
32    tag       string
33    calls     []string
34    ctl       int
35}
36
37func (w *wraprandcaptureCall(tag stringval string) {
38    call := tag + ": " + val + "\n"
39    pc := make([]uintptr10)
40    n := runtime.Callers(1pc)
41    if n == 0 {
42        panic("why?")
43    }
44    pc = pc[:n// pass only valid pcs to runtime.CallersFrames
45    frames := runtime.CallersFrames(pc)
46    for {
47        framemore := frames.Next()
48        if strings.Contains(frame.File"testing.") {
49            break
50        }
51        call += fmt.Sprintf("%s %s:%d\n"frame.Functionframe.Fileframe.Line)
52        if !more {
53            break
54        }
55
56    }
57    w.calls = append(w.callscall)
58}
59
60func (w *wraprandIntn(n int64int64 {
61    w.intncalls++
62    rv := rand.Int63n(n)
63    if w.ctl&RandCtlCapture != 0 {
64        w.captureCall("Intn"fmt.Sprintf("%d"rv))
65    }
66    return rv
67}
68
69func (w *wraprandFloat32() float32 {
70    w.f32calls++
71    rv := rand.Float32()
72    if w.ctl&RandCtlCapture != 0 {
73        w.captureCall("Float32"fmt.Sprintf("%f"rv))
74    }
75    return rv
76}
77
78func (w *wraprandNormFloat64() float64 {
79    w.f64calls++
80    rv := rand.NormFloat64()
81    if w.ctl&RandCtlCapture != 0 {
82        w.captureCall("NormFloat64"fmt.Sprintf("%f"rv))
83    }
84    return rv
85}
86
87func (w *wraprandemitCalls(fn string) {
88    outferr := os.OpenFile(fnos.O_WRONLY|os.O_CREATE|os.O_TRUNC0666)
89    if err != nil {
90        panic(err)
91    }
92    for _c := range w.calls {
93        fmt.Fprint(outfc)
94    }
95    outf.Close()
96}
97
98func (w *wraprandEqual(w2 *wraprandbool {
99    return w.f32calls == w2.f32calls &&
100        w.f64calls == w2.f64calls &&
101        w.intncalls == w2.intncalls
102}
103
104func (w *wraprandCheck(w2 *wraprand) {
105    if w.ctl != 0 && !w.Equal(w2) {
106        fmt.Fprintf(os.Stderr"wraprand consistency check failed:\n")
107        t := "w"
108        if w.tag != "" {
109            t = w.tag
110        }
111        t2 := "w2"
112        if w2.tag != "" {
113            t2 = w2.tag
114        }
115        fmt.Fprintf(os.Stderr" %s: {f32:%d f64:%d i:%d}\n"t,
116            w.f32callsw.f64callsw.intncalls)
117        fmt.Fprintf(os.Stderr" %s: {f32:%d f64:%d i:%d}\n"t2,
118            w2.f32callsw2.f64callsw2.intncalls)
119        if w.ctl&RandCtlCapture != 0 {
120            f := fmt.Sprintf("/tmp/%s.txt"t)
121            f2 := fmt.Sprintf("/tmp/%s.txt"t2)
122            w.emitCalls(f)
123            w2.emitCalls(f2)
124            fmt.Fprintf(os.Stderr"=-= emitted calls to %s, %s\n"ff2)
125        }
126        if w.ctl&RandCtlPanic != 0 {
127            panic("bad")
128        }
129    }
130}
131
132func (w *wraprandCheckpoint(tag string) {
133    if w.ctl&RandCtlCapture != 0 {
134        w.calls = append(w.calls"=-=\n"+tag+"\n=-=\n")
135    }
136}
137
MembersX
wraprand.seed
wraprand.ctl
wraprand.Intn
wraprand.Float32.w
wraprand.emitCalls.err
wraprand.emitCalls.RangeStmt_1781.c
wraprand.intncalls
wraprand.captureCall
wraprand.captureCall.pc
wraprand.captureCall.BlockStmt.frame
wraprand.emitCalls.outf
wraprand.Equal.w
wraprand.Check.BlockStmt.BlockStmt.f
wraprand.Check.BlockStmt.BlockStmt.f2
wraprand.Checkpoint
NewWrapRand
NewWrapRand.seed
wraprand
wraprand.f32calls
wraprand.captureCall.tag
wraprand.captureCall.val
wraprand.emitCalls
wraprand.Check.BlockStmt.t
wraprand.tag
wraprand.calls
wraprand.captureCall.n
wraprand.Equal.w2
wraprand.Check.w
wraprand.Check.w2
NewWrapRand.ctl
wraprand.captureCall.w
wraprand.Intn.rv
wraprand.NormFloat64.w
wraprand.NormFloat64.rv
wraprand.Equal
wraprand.Checkpoint.tag
wraprand.f64calls
wraprand.captureCall.frames
wraprand.Float32
wraprand.Float32.rv
wraprand.emitCalls.fn
wraprand.Check
rand
RandCtlNochecks
wraprand.Intn.w
wraprand.Intn.n
wraprand.Checkpoint.w
wraprand.captureCall.BlockStmt.more
wraprand.NormFloat64
wraprand.emitCalls.w
wraprand.Check.BlockStmt.t2
Members
X