runtime

package
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 3, 2023 License: MIT Imports: 8 Imported by: 0

Documentation

Index

Constants

View Source
const (
	Send   = "Send"
	Recv   = "Recv"
	Close  = "Close"
	Select = "Select"

	MuLock   = "MuLock"
	MuUnlock = "MuUnlock"

	WgWait = "WgWait"

	CdWait      = "CdWait"
	CdSignal    = "CdSignal"
	CdBroadcast = "CdBroadcast"
)
View Source
const MaxRecordElem int = 65536 // 2^16
View Source
const (
	TimeTicker int8 = 1
)

Variables

View Source
var BoolDebug = gogetenv("ORACLERT_DEBUG") == "1"
View Source
var BoolDelayCheck = true
View Source
var BoolRecord bool = true

Settings:

View Source
var BoolRecordPerCh bool = gogetenv("BitGlobalTuple") == "0"
View Source
var BoolRecordSDK bool = gogetenv("GF_SCORE_SDK") == "1"
View Source
var BoolRecordTrad bool = gogetenv("GF_SCORE_TRAD") == "1"
View Source
var BoolReportBug = gogetenv("ORACLERT_BENCHMARK") != "1"

during benchmark, we don't need to print bugs to stdout

View Source
var BoolSelectCount bool
View Source
var ChCount uint16
View Source
var DumpedAllStack bool = false
View Source
var FnCheckCount = func(*uint32) {} // this is defined in gooracle/gooracle.go
View Source
var FnPointer2String func(interface{}) string
View Source
var GlobalEnableOracle = gogetenv("ORACLERT_NOORACLE") != "1"
View Source
var GlobalLastLoc uint32 = uint32(12345)
View Source
var MapBlockEntry map[*BlockEntry]struct{} = make(map[*BlockEntry]struct{})
View Source
var MapChToChanInfo map[interface{}]PrimInfo
View Source
var MapSelectInfo map[string]SelectInfo // useful only when RecordSelectChoice is true
View Source
var MuBlockEntry mutex
View Source
var MuCheckEntry mutex
View Source
var MuFirstInput mutex
View Source
var MuMapChToChanInfo mutex
View Source
var MuReportBug mutex
View Source
var MuWithdraw mutex
View Source
var PtrCheckCounter *uint32
View Source
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

View Source
var StrWithdraw string
View Source
var TupleRecord [MaxRecordElem]uint32
View Source
var Uint32SelectCount uint32
View Source
var VecCheckEntry []*CheckEntry

Functions

func AddRefGoroutine

func AddRefGoroutine(chInfo PrimInfo, goInfo *GoInfo)

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 Breakpoint

func Breakpoint()

Breakpoint executes a breakpoint trap.

func Byte_to_Uint16

func Byte_to_Uint16(b []byte) uint16

func Byte_to_Uint32

func Byte_to_Uint32(b []byte) uint32

func CheckBlockBug

func CheckBlockBug(CS []PrimInfo) (finished bool)

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 CheckBlockEntry() (strReturn string, foundBug bool)

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

func FormatInt(i int64, base int) string

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 GoID

func GoID() int64

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 Index

func Index(s, substr string) int

func IndexByte

func IndexByte(s string, c byte) int

func Itoa

func Itoa(i int) string

Itoa is equivalent to FormatInt(int64(i), 10).

func LastIndex

func LastIndex(s, substr string) int

LastIndex returns the index of the last instance of substr in s, or -1 if substr is not present in s.

func LastIndexByte

func LastIndexByte(s string, c byte) int

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 MyCaller

func MyCaller(skip int) string

MyCaller returns the caller of the function that called it

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 RemoveRefGoroutine(chInfo PrimInfo, goInfo *GoInfo)

func ReportBug

func ReportBug(mapCS map[PrimInfo]struct{})

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 SleepMS

func SleepMS(numMs int)

func StoreChOpInfo

func StoreChOpInfo(strOpType string, uint16OpID uint16)

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 Uint16_to_Byte(b []byte, v uint16)

func Uint32_to_Byte

func Uint32_to_Byte(b []byte, v uint32)

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.

func XorByte

func XorByte(a, b []byte) []byte

func XorUint16

func XorUint16(a, b uint16) uint16

func XorUint32

func XorUint32(a, b uint32) uint32

Types

type BlockEntry

type BlockEntry struct {
	VecPrim       []PrimInfo
	StrOpPosition string
	CurrentGoInfo *GoInfo
}

func EnqueueBlockEntry

func EnqueueBlockEntry(vecPrim []PrimInfo, op string) *BlockEntry

type BlockInfo

type BlockInfo struct {
	Prim  PrimInfo
	StrOp string
}

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

func (chInfo *ChanInfo) AddGoroutine(goInfo *GoInfo)

This means the goroutine mapped with goInfo holds the reference to chInfo.Chan

func (*ChanInfo) LoadMonitor

func (chInfo *ChanInfo) LoadMonitor() uint32

func (*ChanInfo) Lock

func (chInfo *ChanInfo) Lock()

func (*ChanInfo) MapRef

func (chInfo *ChanInfo) MapRef() map[*GoInfo]struct{}

Must be called with chInfo.Mu locked

func (*ChanInfo) RemoveGoroutine

func (chInfo *ChanInfo) RemoveGoroutine(goInfo *GoInfo)

func (*ChanInfo) SetMonitor

func (chInfo *ChanInfo) SetMonitor(i uint32)

func (*ChanInfo) StringDebug

func (chInfo *ChanInfo) StringDebug() string

func (*ChanInfo) Unlock

func (chInfo *ChanInfo) Unlock()

type ChanRecord

type ChanRecord struct {
	StrCreation string // Example: "/data/ziheng/shared/gotest/stubs/toy/src/toy/main_test.go:34"
	Closed      bool
	NotClosed   bool
	CapBuf      uint16
	PeakBuf     uint16
	Ch          *hchan
}

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

func (cond *CondInfo) AddGoroutine(goInfo *GoInfo)

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 (c *CondInfo) LoadMonitor() uint32

func (*CondInfo) Lock

func (cond *CondInfo) Lock()

func (*CondInfo) MapRef

func (cond *CondInfo) MapRef() map[*GoInfo]struct{}

Must be called with lock

func (*CondInfo) RemoveGoroutine

func (cond *CondInfo) RemoveGoroutine(goInfo *GoInfo)

Must be called when chInfo.Chan.lock is held

func (*CondInfo) SetMonitor

func (c *CondInfo) SetMonitor(i uint32)

func (*CondInfo) StringDebug

func (c *CondInfo) StringDebug() string

func (*CondInfo) Unlock

func (cond *CondInfo) Unlock()

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 NewGoInfo

func NewGoInfo(goroutine *g) *GoInfo

Initialize a GoInfo

func (*GoInfo) AddPrime

func (goInfo *GoInfo) AddPrime(chInfo PrimInfo)

This means the goroutine mapped with goInfo holds the reference to chInfo.Chan

func (*GoInfo) IsBlock

func (goInfo *GoInfo) IsBlock() (boolIsBlock bool, strOp string)

func (*GoInfo) IsBlockAtGivenChan

func (goInfo *GoInfo) IsBlockAtGivenChan(chInfo *ChanInfo) (boolIsBlockAtGiven bool, strOp string)

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 *GoInfo) RemovePrime(chInfo PrimInfo)

func (*GoInfo) SetBlockAt

func (goInfo *GoInfo) SetBlockAt(prim PrimInfo, strOp string)

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 NewMuInfo

func NewMuInfo() *MuInfo

func (*MuInfo) AddGoroutine

func (mu *MuInfo) AddGoroutine(goInfo *GoInfo)

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 (m *MuInfo) LoadMonitor() uint32

func (*MuInfo) Lock

func (mu *MuInfo) Lock()

func (*MuInfo) MapRef

func (mu *MuInfo) MapRef() map[*GoInfo]struct{}

Must be called with lock

func (*MuInfo) RemoveGoroutine

func (mu *MuInfo) RemoveGoroutine(goInfo *GoInfo)

Must be called when chInfo.Chan.lock is held

func (*MuInfo) SetMonitor

func (m *MuInfo) SetMonitor(i uint32)

func (*MuInfo) StringDebug

func (m *MuInfo) StringDebug() string

func (*MuInfo) Unlock

func (mu *MuInfo) Unlock()

type OpType

type OpType uint8
const (
	ChSend   OpType = 1
	ChRecv   OpType = 2
	ChClose  OpType = 3
	ChSelect OpType = 4
)

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

func (mu *RWMuInfo) AddGoroutine(goInfo *GoInfo)

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 (m *RWMuInfo) LoadMonitor() uint32

func (*RWMuInfo) Lock

func (mu *RWMuInfo) Lock()

func (*RWMuInfo) MapRef

func (mu *RWMuInfo) MapRef() map[*GoInfo]struct{}

Must be called with lock

func (*RWMuInfo) RemoveGoroutine

func (mu *RWMuInfo) RemoveGoroutine(goInfo *GoInfo)

Must be called when chInfo.Chan.lock is held

func (*RWMuInfo) SetMonitor

func (m *RWMuInfo) SetMonitor(i uint32)

func (*RWMuInfo) StringDebug

func (m *RWMuInfo) StringDebug() string

func (*RWMuInfo) Unlock

func (mu *RWMuInfo) Unlock()

type SelectInfo

type SelectInfo struct {
	StrFileName string
	StrLineNum  string
	IntNumCase  int
	IntPrioCase int
}

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 NewWgInfo

func NewWgInfo() *WgInfo

func (*WgInfo) AddGoroutine

func (w *WgInfo) AddGoroutine(goInfo *GoInfo)

This means the goroutine mapped with goInfo holds the reference to chInfo.Chan Must be called when chInfo.Chan.lock is held

func (*WgInfo) IamBug

func (w *WgInfo) IamBug()

func (*WgInfo) LoadMonitor

func (w *WgInfo) LoadMonitor() uint32

func (*WgInfo) Lock

func (w *WgInfo) Lock()

func (*WgInfo) MapRef

func (w *WgInfo) MapRef() map[*GoInfo]struct{}

Must be called with lock

func (*WgInfo) RemoveGoroutine

func (w *WgInfo) RemoveGoroutine(goInfo *GoInfo)

Must be called when chInfo.Chan.lock is held

func (*WgInfo) SetMonitor

func (w *WgInfo) SetMonitor(i uint32)

func (*WgInfo) StringDebug

func (w *WgInfo) StringDebug() string

func (*WgInfo) Unlock

func (w *WgInfo) Unlock()

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL