Closed
Description
The function analysis.AnalyzePkg doesn't get the blocking right when a function literal calls another function that only later is determined to require blocking. The call site of the function literal is not retained for later handling.
A short main.go program that demonstrates the problem.
package main
import "runtime"
func main() {
foo()
println("main done")
}
// Problem: foo is not recognized as a blocking function.
//
// TLDR; function literals aren't handled identically to defined functions
// in analysis/info.go and a call stack is not kept for later use.
//
// Short cause analysis: the function literal called in foo is not determined
// to be blocking until later in analysis/info.go when it is determined that bar
// is blocking. The FuncLit itself is recognized as blocking later on once bar
// has been analyzed, but not foo: while foo was being analyzed the call site
// stack within it was not saved for later use. So the call site effectively
// falls through and is left as unblocking, so foo is left as unblocking, so
// main is left as unblocking.
func foo() {
func() { bar() }()
println("foo done")
}
func bar() {
runtime.Gosched()
}