github.com/lzhfromustc/gofuzz@v0.0.0-20211116160056-151b3108bbd1/runtime/myrecord.go (about) 1 package runtime 2 3 import ( 4 "sync/atomic" 5 ) 6 7 const MaxRecordElem int = 65536 // 2^16 8 9 // Settings: 10 var BoolRecord bool = true 11 var BoolRecordPerCh bool = gogetenv("BitGlobalTuple") == "0" 12 var BoolRecordSDK bool = gogetenv("GF_SCORE_SDK") == "1" 13 var BoolRecordTrad bool = gogetenv("GF_SCORE_TRAD") == "1" 14 15 // TODO: important: extend similar algorithm for mutex, conditional variable, waitgroup, etc 16 17 // For the record of each channel: 18 19 type ChanRecord struct { 20 StrCreation string // Example: "/data/ziheng/shared/gotest/stubs/toy/src/toy/main_test.go:34" 21 Closed bool 22 NotClosed bool 23 CapBuf uint16 24 PeakBuf uint16 25 Ch *hchan 26 } 27 28 var ChRecord [MaxRecordElem]*ChanRecord 29 30 // For the record of each channel operation 31 32 var GlobalLastLoc uint32 = uint32(12345) 33 var TupleRecord [MaxRecordElem]uint32 34 var ChCount uint16 35 36 var BoolPrintDebugInfo bool = false 37 38 // When a channel is made, create new id, new ChanRecord 39 func RecordChMake(capBuf int, c *hchan) { 40 41 if BoolRecordSDK == false { 42 if c.chInfo.BoolInSDK == false { 43 return 44 } 45 } 46 47 c.id = ChCount 48 ChCount++ 49 50 newChRecord := &ChanRecord{ 51 StrCreation: c.chInfo.StrDebug, 52 Closed: false, 53 NotClosed: true, 54 CapBuf: uint16(capBuf), 55 PeakBuf: 0, 56 Ch: c, 57 } 58 59 ChRecord[c.id] = newChRecord 60 c.chanRecord = newChRecord 61 } 62 63 // When a channel operation is executed, update TupleRecord, and update the tuple counter (curLoc XOR prevLoc) 64 func RecordChOp(c *hchan) { 65 66 // As mentioned above, we don't record channels created in runtime 67 if c.chanRecord == nil { 68 return 69 } 70 if BoolRecordSDK == false { 71 if c.chInfo.BoolInSDK == false { 72 if BoolPrintDebugInfo { 73 println("For the channel", c.chInfo.StrDebug, ", we don't record its operation") 74 } 75 return 76 } 77 if BoolPrintDebugInfo { 78 println("For the channel", c.chInfo.StrDebug, ", we recorded its operation") 79 } 80 } 81 82 // Update ChanRecord 83 //print("qcount:",c.qcount, "dataqsiz", c.dataqsiz, "elemsize", c.elemsize, "\n") 84 if c.chanRecord.PeakBuf < uint16(c.qcount) { // TODO: only execute this when it is a send operation 85 c.chanRecord.PeakBuf = uint16(c.qcount) 86 //print("ch:", c.chanRecord.StrCreation, "\tpeakBuf:", c.chanRecord.PeakBuf, "\n") 87 } 88 c.chanRecord.Closed = c.closed == 1 // TODO: only execute this when it is a close operation 89 if c.chanRecord.Closed { 90 c.chanRecord.NotClosed = false 91 } 92 93 curLoc := getg().uint16OpID 94 var preLoc, xorLoc uint16 95 if BoolRecordPerCh { 96 preLoc = c.preLoc // This may data race 97 c.preLoc = curLoc >> 1 98 } else { 99 preLoc = uint16(atomic.LoadUint32(&GlobalLastLoc)) 100 atomic.StoreUint32(&GlobalLastLoc, uint32(curLoc>>1)) 101 } 102 xorLoc = XorUint16(curLoc, preLoc) 103 104 atomic.AddUint32(&TupleRecord[xorLoc], 1) 105 } 106 107 // When a traditional primitive operation is executed, update TupleRecord, and update the tuple counter (curLoc XOR prevLoc) 108 // If BoolRecordTrad is false, this function won't be called. See sync package 109 func RecordTradOp(primPreLoc *uint16) { 110 curLoc := getg().uint16OpID 111 var preLoc, xorLoc uint16 112 if BoolRecordPerCh { 113 preLoc = *primPreLoc // This may data race 114 *primPreLoc = curLoc >> 1 115 } else { 116 preLoc = uint16(atomic.LoadUint32(&GlobalLastLoc)) 117 atomic.StoreUint32(&GlobalLastLoc, uint32(curLoc>>1)) 118 } 119 xorLoc = XorUint16(curLoc, preLoc) 120 atomic.AddUint32(&TupleRecord[xorLoc], 1) 121 } 122 123 func StoreChOpInfo(strOpType string, uint16OpID uint16) { 124 getg().strChOpType = strOpType 125 getg().uint16OpID = uint16OpID 126 } 127 128 func CurrentGoAddMutex(ch interface{}) { 129 lock(&MuMapChToChanInfo) 130 chInfo, exist := MapChToChanInfo[ch] 131 unlock(&MuMapChToChanInfo) 132 if !exist { 133 return 134 } 135 AddRefGoroutine(chInfo, CurrentGoInfo()) 136 } 137 138 func CurrentGoAddCond(ch interface{}) { 139 lock(&MuMapChToChanInfo) 140 chInfo, exist := MapChToChanInfo[ch] 141 unlock(&MuMapChToChanInfo) 142 if !exist { 143 return 144 } 145 AddRefGoroutine(chInfo, CurrentGoInfo()) 146 } 147 148 func CurrentGoAddWaitgroup(ch interface{}) { 149 lock(&MuMapChToChanInfo) 150 chInfo, exist := MapChToChanInfo[ch] 151 unlock(&MuMapChToChanInfo) 152 if !exist { 153 return 154 } 155 AddRefGoroutine(chInfo, CurrentGoInfo()) 156 }