EnterFunc marks the beginning of a function. Calling fn should be equivalent to running the function that is being entered. If proceed is false, EnterFunc did in fact call fn, and so the caller of EnterFunc should return immediately rather than proceed to duplicate the effects of fn.

EnterFunc is referenced in 0 repositories


func EnterFunc(fn func()) (ctx *Context, proceed bool) {
	// We've entered a new function. If we're in step or next mode we have some bookkeeping to do,
	// but only if the current goroutine is the one the debugger is following.
	// We consult context to determine whether we are the goroutine the debugger is following. If
	// context has not seen our goroutine before, the ok it returns is false. Why would that happen?
	// godebug supports generating debug code for a library that is later built into a binary. If that
	// happens, then context will not see any goroutines until they call code from the debugged library.
	// context will also not see any goroutines while the debugger is in state run.
	val, ok := context.GetValue(goroutineKey)
	if !ok {
		// This is the first time context has seen the current goroutine.
		// Or, more accurately and precisely: This is the first frame in the current stack that contains
		// code that has been generated by godebug.
		// We record some bookkeeping information with context and then continue running. This means we will
		// invoke fn, which means the caller should not proceed. After running it, return false.
		id := uint32(ids.Acquire())
		defer ids.Release(uint(id))
		context.SetValues(fn, goroutineKey, id)
		return nil, false
	if val.(uint32) == atomic.LoadUint32(&currentGoroutine) && currentState != run {
		if justLeft {
			// This means this goroutine ran ExitFunc followed by EnterFunc with no intervening debug calls,
			// probably because the parent caller is in another package which has not been instrumented.
			justLeft = false
	return &Context{goroutine: val.(uint32)}, true