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  }