Documentation ¶
Index ¶
- Constants
- Variables
- func AddRefGoroutine(chInfo PrimInfo, goInfo *GoInfo)
- func BoolCheckEntryEqual(a, b *CheckEntry) bool
- func Breakpoint()
- func Byte_to_Uint16(b []byte) uint16
- func Byte_to_Uint32(b []byte) uint32
- func CheckBlockBug(CS []PrimInfo) (finished bool)
- func CheckBlockEntry() (strReturn string, foundBug bool)
- func CurrentGoAddCh(ch interface{})
- func CurrentGoAddCond(ch interface{})
- func CurrentGoAddMutex(ch interface{})
- func CurrentGoAddWaitgroup(ch interface{})
- func CurrentGoID() int64
- func DequeueBlockEntry(entry *BlockEntry)
- func DumpAllStack()
- func FormatInt(i int64, base int) string
- func GoID() int64
- func Gosched()
- func Index(s, substr string) int
- func IndexByte(s string, c byte) int
- func Itoa(i int) string
- func LastIndex(s, substr string) int
- func LastIndexByte(s string, c byte) int
- func LastMySwitchChoice() int
- func LastMySwitchLineNum() string
- func LastMySwitchOriSelectNumCase() int
- func LinkChToLastChanInfo(ch interface{})
- func LinkCondToLastCondInfo(cond interface{})
- func LinkMuToLastMuInfo(mu interface{})
- func LinkRWMuToLastRWMuInfo(rwmu interface{})
- func LinkWgToLastWgInfo(wg interface{})
- func LockCheckEntry()
- func LockOSThread()
- func Monitor(prim PrimInfo)
- func MyCaller(skip int) string
- func PrintCurrentStack()
- func ProcessSelectInfo(handler func(map[string]SelectInfo))
- func ReadSelectCount() uint32
- func RecordChMake(capBuf int, c *hchan)
- func RecordChOp(c *hchan)
- func RecordTradOp(primPreLoc *uint16)
- func RemoveRefGoroutine(chInfo PrimInfo, goInfo *GoInfo)
- func ReportBug(mapCS map[PrimInfo]struct{})
- func ReportNonBlockingBug()
- func SelectCount()
- func SetCurrentGoCheckBug()
- func SleepMS(numMs int)
- func StoreChOpInfo(strOpType string, uint16OpID uint16)
- func StoreLastMySwitchChoice(choice int)
- func StoreLastMySwitchLineNum(strLine string)
- func StoreLastMySwitchSelectNumCase(numCase int)
- func StoreLastPrimInfo(chInfo PrimInfo)
- func StoreSelectInput(intNumCase, intChosenCase int)
- func Uint16_to_Byte(b []byte, v uint16)
- func Uint32_to_Byte(b []byte, v uint32)
- func UnlockCheckEntry()
- func UnlockOSThread()
- func XorByte(a, b []byte) []byte
- func XorUint16(a, b uint16) uint16
- func XorUint32(a, b uint32) uint32
- type BlockEntry
- type BlockInfo
- type ChanInfo
- func (chInfo *ChanInfo) AddGoroutine(goInfo *GoInfo)
- func (chInfo *ChanInfo) LoadMonitor() uint32
- func (chInfo *ChanInfo) Lock()
- func (chInfo *ChanInfo) MapRef() map[*GoInfo]struct{}
- func (chInfo *ChanInfo) RemoveGoroutine(goInfo *GoInfo)
- func (chInfo *ChanInfo) SetMonitor(i uint32)
- func (chInfo *ChanInfo) StringDebug() string
- func (chInfo *ChanInfo) Unlock()
- type ChanRecord
- type CheckEntry
- type CondInfo
- func (cond *CondInfo) AddGoroutine(goInfo *GoInfo)
- func (c *CondInfo) LoadMonitor() uint32
- func (cond *CondInfo) Lock()
- func (cond *CondInfo) MapRef() map[*GoInfo]struct{}
- func (cond *CondInfo) RemoveGoroutine(goInfo *GoInfo)
- func (c *CondInfo) SetMonitor(i uint32)
- func (c *CondInfo) StringDebug() string
- func (cond *CondInfo) Unlock()
- type GoInfo
- func (goInfo *GoInfo) AddPrime(chInfo PrimInfo)
- func (goInfo *GoInfo) IsBlock() (boolIsBlock bool, strOp string)
- func (goInfo *GoInfo) IsBlockAtGivenChan(chInfo *ChanInfo) (boolIsBlockAtGiven bool, strOp string)
- func (goInfo *GoInfo) RemoveAllRef()
- func (goInfo *GoInfo) RemovePrime(chInfo PrimInfo)
- func (goInfo *GoInfo) SetBlockAt(prim PrimInfo, strOp string)
- func (goInfo *GoInfo) SetCheckBug()
- func (goInfo *GoInfo) SetNotCheckBug()
- func (goInfo *GoInfo) WithdrawBlock(checkEntry *CheckEntry)
- type MuInfo
- func (mu *MuInfo) AddGoroutine(goInfo *GoInfo)
- func (m *MuInfo) LoadMonitor() uint32
- func (mu *MuInfo) Lock()
- func (mu *MuInfo) MapRef() map[*GoInfo]struct{}
- func (mu *MuInfo) RemoveGoroutine(goInfo *GoInfo)
- func (m *MuInfo) SetMonitor(i uint32)
- func (m *MuInfo) StringDebug() string
- func (mu *MuInfo) Unlock()
- type OpType
- type PrimInfo
- type RWMuInfo
- func (mu *RWMuInfo) AddGoroutine(goInfo *GoInfo)
- func (m *RWMuInfo) LoadMonitor() uint32
- func (mu *RWMuInfo) Lock()
- func (mu *RWMuInfo) MapRef() map[*GoInfo]struct{}
- func (mu *RWMuInfo) RemoveGoroutine(goInfo *GoInfo)
- func (m *RWMuInfo) SetMonitor(i uint32)
- func (m *RWMuInfo) StringDebug() string
- func (mu *RWMuInfo) Unlock()
- type SelectInfo
- type StackSingleGo
- type WgInfo
- func (w *WgInfo) AddGoroutine(goInfo *GoInfo)
- func (w *WgInfo) IamBug()
- func (w *WgInfo) LoadMonitor() uint32
- func (w *WgInfo) Lock()
- func (w *WgInfo) MapRef() map[*GoInfo]struct{}
- func (w *WgInfo) RemoveGoroutine(goInfo *GoInfo)
- func (w *WgInfo) SetMonitor(i uint32)
- func (w *WgInfo) StringDebug() string
- func (w *WgInfo) Unlock()
Constants ¶
const ( Send = "Send" Recv = "Recv" Close = "Close" Select = "Select" MuLock = "MuLock" MuUnlock = "MuUnlock" WgWait = "WgWait" CdWait = "CdWait" CdSignal = "CdSignal" CdBroadcast = "CdBroadcast" )
const MaxRecordElem int = 65536 // 2^16
const (
TimeTicker int8 = 1
)
Variables ¶
var BoolDebug = gogetenv("ORACLERT_DEBUG") == "1"
var BoolDelayCheck = true
var BoolRecord bool = true
Settings:
var BoolRecordPerCh bool = gogetenv("BitGlobalTuple") == "0"
var BoolRecordSDK bool = gogetenv("GF_SCORE_SDK") == "1"
var BoolRecordTrad bool = gogetenv("GF_SCORE_TRAD") == "1"
var BoolReportBug = gogetenv("ORACLERT_BENCHMARK") != "1"
during benchmark, we don't need to print bugs to stdout
var BoolSelectCount bool
var ChCount uint16
var ChRecord [MaxRecordElem]*ChanRecord
var DumpedAllStack bool = false
var FnCheckCount = func(*uint32) {} // this is defined in gooracle/gooracle.go
var FnPointer2String func(interface{}) string
var GlobalEnableOracle = gogetenv("ORACLERT_NOORACLE") != "1"
var GlobalLastLoc uint32 = uint32(12345)
var MapBlockEntry map[*BlockEntry]struct{} = make(map[*BlockEntry]struct{})
var MapChToChanInfo map[interface{}]PrimInfo
var MapSelectInfo map[string]SelectInfo // useful only when RecordSelectChoice is true
var MuBlockEntry mutex
var MuCheckEntry mutex
var MuFirstInput mutex
var MuMapChToChanInfo mutex
var MuReportBug mutex
var MuWithdraw mutex
var PtrCheckCounter *uint32
var RecordSelectChoice bool = true // by default is true, we need to collect if new select has been found
var MapInput map[string]SelectInfo // useful only when RecordSelectChoice is false
var StrWithdraw string
var TupleRecord [MaxRecordElem]uint32
var Uint32SelectCount uint32
var VecCheckEntry []*CheckEntry
Functions ¶
func AddRefGoroutine ¶
After the creation of a new channel, or at the head of a goroutine that holds a reference to a channel, or whenever a goroutine obtains a reference to a channel, call this function AddRefGoroutine links a channel with a goroutine, meaning the goroutine holds the reference to the channel
func BoolCheckEntryEqual ¶
func BoolCheckEntryEqual(a, b *CheckEntry) bool
func Byte_to_Uint16 ¶
func Byte_to_Uint32 ¶
func CheckBlockBug ¶
A blocking bug is detected, if all goroutines that hold the reference to a channel are blocked at an operation of the channel finished is true when we are sure that CS doesn't need to be checked again
func CheckBlockEntry ¶
func CurrentGoAddCh ¶
func CurrentGoAddCh(ch interface{})
func CurrentGoAddCond ¶
func CurrentGoAddCond(ch interface{})
func CurrentGoAddMutex ¶
func CurrentGoAddMutex(ch interface{})
func CurrentGoAddWaitgroup ¶
func CurrentGoAddWaitgroup(ch interface{})
func CurrentGoID ¶
func CurrentGoID() int64
func DequeueBlockEntry ¶
func DequeueBlockEntry(entry *BlockEntry)
func DumpAllStack ¶
func DumpAllStack()
func FormatInt ¶
FormatInt returns the string representation of i in the given base, for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z' for digit values >= 10.
func Gosched ¶
func Gosched()
Gosched yields the processor, allowing other goroutines to run. It does not suspend the current goroutine, so execution resumes automatically.
func LastIndex ¶
LastIndex returns the index of the last instance of substr in s, or -1 if substr is not present in s.
func LastIndexByte ¶
LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
func LastMySwitchChoice ¶
func LastMySwitchChoice() int
func LastMySwitchLineNum ¶
func LastMySwitchLineNum() string
func LastMySwitchOriSelectNumCase ¶
func LastMySwitchOriSelectNumCase() int
func LinkChToLastChanInfo ¶
func LinkChToLastChanInfo(ch interface{})
func LinkCondToLastCondInfo ¶
func LinkCondToLastCondInfo(cond interface{})
func LinkMuToLastMuInfo ¶
func LinkMuToLastMuInfo(mu interface{})
func LinkRWMuToLastRWMuInfo ¶
func LinkRWMuToLastRWMuInfo(rwmu interface{})
func LinkWgToLastWgInfo ¶
func LinkWgToLastWgInfo(wg interface{})
func LockCheckEntry ¶
func LockCheckEntry()
func LockOSThread ¶
func LockOSThread()
LockOSThread wires the calling goroutine to its current operating system thread. The calling goroutine will always execute in that thread, and no other goroutine will execute in it, until the calling goroutine has made as many calls to UnlockOSThread as to LockOSThread. If the calling goroutine exits without unlocking the thread, the thread will be terminated.
All init functions are run on the startup thread. Calling LockOSThread from an init function will cause the main function to be invoked on that thread.
A goroutine should call LockOSThread before calling OS services or non-Go library functions that depend on per-thread state.
func Monitor ¶
func Monitor(prim PrimInfo)
If PrimInfo.LoadMonitor is 1, a bug has been reported based on the assumption that this prim won't be reached again However, this Monitor() is still invoked, meaning our assumption is incorrect. Withdraw the bug If this is really a bug, it will be reported later again
func PrintCurrentStack ¶
func PrintCurrentStack()
func ProcessSelectInfo ¶
func ProcessSelectInfo(handler func(map[string]SelectInfo))
func ReadSelectCount ¶
func ReadSelectCount() uint32
func RecordChMake ¶
func RecordChMake(capBuf int, c *hchan)
When a channel is made, create new id, new ChanRecord
func RecordChOp ¶
func RecordChOp(c *hchan)
When a channel operation is executed, update TupleRecord, and update the tuple counter (curLoc XOR prevLoc)
func RecordTradOp ¶
func RecordTradOp(primPreLoc *uint16)
When a traditional primitive operation is executed, update TupleRecord, and update the tuple counter (curLoc XOR prevLoc) If BoolRecordTrad is false, this function won't be called. See sync package
func RemoveRefGoroutine ¶
func ReportNonBlockingBug ¶
func ReportNonBlockingBug()
func SelectCount ¶
func SelectCount()
func SetCurrentGoCheckBug ¶
func SetCurrentGoCheckBug()
When this goroutine is checking bug, set goInfo.BitCheckBugAtEnd to be 1
func StoreChOpInfo ¶
func StoreLastMySwitchChoice ¶
func StoreLastMySwitchChoice(choice int)
func StoreLastMySwitchLineNum ¶
func StoreLastMySwitchLineNum(strLine string)
func StoreLastMySwitchSelectNumCase ¶
func StoreLastMySwitchSelectNumCase(numCase int)
func StoreLastPrimInfo ¶
func StoreLastPrimInfo(chInfo PrimInfo)
func StoreSelectInput ¶
func StoreSelectInput(intNumCase, intChosenCase int)
func Uint16_to_Byte ¶
func Uint32_to_Byte ¶
func UnlockCheckEntry ¶
func UnlockCheckEntry()
func UnlockOSThread ¶
func UnlockOSThread()
UnlockOSThread undoes an earlier call to LockOSThread. If this drops the number of active LockOSThread calls on the calling goroutine to zero, it unwires the calling goroutine from its fixed operating system thread. If there are no active LockOSThread calls, this is a no-op.
Before calling UnlockOSThread, the caller must ensure that the OS thread is suitable for running other goroutines. If the caller made any permanent changes to the state of the thread that would affect other goroutines, it should not call this function and thus leave the goroutine locked to the OS thread until the goroutine (and hence the thread) exits.
Types ¶
type BlockEntry ¶
func EnqueueBlockEntry ¶
func EnqueueBlockEntry(vecPrim []PrimInfo, op string) *BlockEntry
type ChanInfo ¶
type ChanInfo struct { Chan *hchan // Stores the channel. Can be used as ID of channel IntBuffer int // The buffer capability of channel. 0 if channel is unbuffered MapRefGoroutine map[*GoInfo]struct{} // Stores all goroutines that still hold reference to this channel StrDebug string OKToCheck bool // Disable oracle for not instrumented channels BoolInSDK bool // Disable oracle for channels in SDK IntFlagFoundBug int32 // Use atomic int32 operations to mark if a bug is reported Mu mutex SpecialFlag int8 Uint32Monitor uint32 // Default: 0. When a bug is based on the assumption that this primitive won't execute again, set to 1. }
ChanInfo is 1-to-1 with every channel. It tracks a list of goroutines that hold the reference to the channel
func FindChanInfo ¶
func FindChanInfo(ch interface{}) *ChanInfo
FindChanInfo can retrieve a initialized ChanInfo for a given channel
func NewChanInfo ¶
func NewChanInfo(ch *hchan) *ChanInfo
Initialize a new ChanInfo with a given channel
func (*ChanInfo) AddGoroutine ¶
This means the goroutine mapped with goInfo holds the reference to chInfo.Chan
func (*ChanInfo) LoadMonitor ¶
func (*ChanInfo) RemoveGoroutine ¶
func (*ChanInfo) SetMonitor ¶
func (*ChanInfo) StringDebug ¶
type ChanRecord ¶
type CheckEntry ¶
type CheckEntry struct { CS []PrimInfo Uint32NeedCheck uint32 // if 0, delete this CheckEntry; if 1, check this CheckEntry }
Only when BoolDelayCheck is true, this struct is used CheckEntry contains information needed for a CheckBlockBug
func DequeueCheckEntry ¶
func DequeueCheckEntry() *CheckEntry
func EnqueueCheckEntry ¶
func EnqueueCheckEntry(CS []PrimInfo) *CheckEntry
type CondInfo ¶
type CondInfo struct { MapRefGoroutine map[*GoInfo]struct{} StrDebug string EnableOracle bool // Disable oracle for channels in SDK IntFlagFoundBug int32 // Use atomic int32 operations to mark if a bug is reported Mu mutex // Protects MapRefGoroutine Uint32Monitor uint32 }
CondInfo is 1-to-1 with every sync.Cond.
func FindCondInfo ¶
func FindCondInfo(cond interface{}) *CondInfo
FindChanInfo can retrieve a initialized ChanInfo for a given channel
func NewCondInfo ¶
func NewCondInfo() *CondInfo
func (*CondInfo) AddGoroutine ¶
This means the goroutine mapped with goInfo holds the reference to chInfo.Chan Must be called when chInfo.Chan.lock is held
func (*CondInfo) LoadMonitor ¶
func (*CondInfo) RemoveGoroutine ¶
Must be called when chInfo.Chan.lock is held
func (*CondInfo) SetMonitor ¶
func (*CondInfo) StringDebug ¶
type GoInfo ¶
type GoInfo struct { G *g VecBlockInfo []BlockInfo // Nil when normally running. When blocked at an operation of ChanInfo, store // one ChanInfo and the operation. When blocked at select, store multiple ChanInfo and // operation. Default in select is also also stored in map, which is DefaultCaseChanInfo BitCheckBugAtEnd uint32 // 0 when normally running. 1 when this goroutine is checking bug. MapPrimeInfo map[PrimInfo]struct{} // Stores all channels that this goroutine still hold reference to Mu mutex // protects VecBlockInfo and MapPrimeInfo }
GoInfo is 1-to-1 with each goroutine. Go language doesn't allow us to acquire the ID of a goroutine, because they want goroutines to be anonymous. Normally, Go programmers use runtime.Stack() to print all IDs of all goroutines, but this function is very inefficient , since it calls stopTheWorld() Currently we use a global atomic int64 to differentiate each goroutine, and a variable currentGo to represent each goroutine This is not a good practice because the goroutine need to pass currentGo to its every callee
func CurrentGoInfo ¶
func CurrentGoInfo() *GoInfo
func (*GoInfo) AddPrime ¶
This means the goroutine mapped with goInfo holds the reference to chInfo.Chan
func (*GoInfo) IsBlockAtGivenChan ¶
This function checks if the goroutine mapped with goInfo is currently blocking at an operation of chInfo.Chan If so, returns true and the string of channel operation
func (*GoInfo) RemoveAllRef ¶
func (goInfo *GoInfo) RemoveAllRef()
RemoveRef should be called at the end of every goroutine. It will remove goInfo from the reference list of every channel it holds the reference to
func (*GoInfo) RemovePrime ¶
func (*GoInfo) SetBlockAt ¶
SetBlockAt should be called before each channel operation, meaning the current goroutine is about to execute that operation Note that we check bug in this function, because it's possible for the goroutine to be blocked forever if it execute that operation For example, a channel with no buffer is held by a parent and a child.
The parent has already exited, but the child is now about to send to that channel. Then now is our only chance to detect this bug, so we call CheckBlockBug()
func (*GoInfo) SetCheckBug ¶
func (goInfo *GoInfo) SetCheckBug()
func (*GoInfo) SetNotCheckBug ¶
func (goInfo *GoInfo) SetNotCheckBug()
func (*GoInfo) WithdrawBlock ¶
func (goInfo *GoInfo) WithdrawBlock(checkEntry *CheckEntry)
WithdrawBlock should be called after each channel operation, meaning the current goroutine finished execution that operation If the operation is select, remember to call this function right after each case of the select
type MuInfo ¶
type MuInfo struct { MapRefGoroutine map[*GoInfo]struct{} StrDebug string EnableOracle bool // Disable oracle for channels in SDK IntFlagFoundBug int32 // Use atomic int32 operations to mark if a bug is reported Mu mutex // Protects MapRefGoroutine Uint32Monitor uint32 }
MuInfo is 1-to-1 with every sync.Mutex.
func FindMuInfo ¶
func FindMuInfo(mu interface{}) *MuInfo
FindChanInfo can retrieve a initialized ChanInfo for a given channel
func (*MuInfo) AddGoroutine ¶
This means the goroutine mapped with goInfo holds the reference to chInfo.Chan Must be called when chInfo.Chan.lock is held
func (*MuInfo) LoadMonitor ¶
func (*MuInfo) RemoveGoroutine ¶
Must be called when chInfo.Chan.lock is held
func (*MuInfo) SetMonitor ¶
func (*MuInfo) StringDebug ¶
type PrimInfo ¶
type PrimInfo interface { Lock() Unlock() MapRef() map[*GoInfo]struct{} AddGoroutine(*GoInfo) RemoveGoroutine(*GoInfo) StringDebug() string SetMonitor(uint32) LoadMonitor() uint32 }
func LoadLastPrimInfo ¶
func LoadLastPrimInfo() PrimInfo
type RWMuInfo ¶
type RWMuInfo struct { MapRefGoroutine map[*GoInfo]struct{} StrDebug string EnableOracle bool // Disable oracle for channels in SDK IntFlagFoundBug int32 // Use atomic int32 operations to mark if a bug is reported Mu mutex // Protects MapRefGoroutine Uint32Monitor uint32 }
RWMuInfo is 1-to-1 with every sync.RWMutex.
func FindRWMuInfo ¶
func FindRWMuInfo(rwmu interface{}) *RWMuInfo
FindChanInfo can retrieve a initialized ChanInfo for a given channel
func NewRWMuInfo ¶
func NewRWMuInfo() *RWMuInfo
func (*RWMuInfo) AddGoroutine ¶
This means the goroutine mapped with goInfo holds the reference to chInfo.Chan Must be called when chInfo.Chan.lock is held
func (*RWMuInfo) LoadMonitor ¶
func (*RWMuInfo) RemoveGoroutine ¶
Must be called when chInfo.Chan.lock is held
func (*RWMuInfo) SetMonitor ¶
func (*RWMuInfo) StringDebug ¶
type SelectInfo ¶
func NewSelectInputFromRuntime ¶
func NewSelectInputFromRuntime(intNumCase, intPrioCase int, intLayerCallee int) SelectInfo
type StackSingleGo ¶
type StackSingleGo struct { GoID string GoStatus string // this may not help VecFuncName, VecFuncFile, VecFuncLine []string CreaterName, CreaterFile, CreaterLine string OnOtherThread bool // Sometimes the stack is unavailable, if the goroutine is on another thread }
func ParseStackStr ¶
func ParseStackStr(stackStr string) StackSingleGo
type WgInfo ¶
type WgInfo struct { WgCounter uint32 MapRefGoroutine map[*GoInfo]struct{} StrDebug string EnableOracle bool // Disable oracle for channels in SDK IntFlagFoundBug int32 // Use atomic int32 operations to mark if a bug is reported Mu mutex // Protects MapRefGoroutine Uint32Monitor uint32 }
WgInfo is 1-to-1 with every WaitGroup.
func FindWgInfo ¶
func FindWgInfo(wg interface{}) *WgInfo
FindChanInfo can retrieve a initialized ChanInfo for a given channel
func (*WgInfo) AddGoroutine ¶
This means the goroutine mapped with goInfo holds the reference to chInfo.Chan Must be called when chInfo.Chan.lock is held
func (*WgInfo) LoadMonitor ¶
func (*WgInfo) RemoveGoroutine ¶
Must be called when chInfo.Chan.lock is held