Join GitHub today
runtime: "internal error: misuse of lockOSThread/unlockOSThread" in runOpenDeferFrame #35277
I tried to reproduce by running
However, this might have to do with the fact that runtime.main only leaves the function via exit(0) (which is followed by an infinite loop), so there is no explicit function return/exit where inline defer code is generated. Hence, the implicit &needUnlock argument to the defer closure is not necessarily kept alive, so it may not get adjusted if there is a stack move. I should maybe just make all OpenDeferSlots live through out the entire function.
Once defined, a stack slot holding an open-coded defer arg should always be marked live, since it may be used at any time if there is a panic. These stack slots are typically kept live naturally by the open-defer code inlined at each return/exit point. However, we need to do extra work to make sure that they are kept live if a function has an infinite loop or a panic exit. For this fix, only in the case of a function that is using open-coded defers, we compute the set of blocks (most often empty) that cannot reach a return or a BlockExit (panic) because of an infinite loop. Then, for each block b which cannot reach a return or BlockExit or is a BlockExit block, we mark each defer arg slot as live, as long as the definition of the defer arg slot dominates block b. For this change, had to export (*Func).sdom (-> Sdom) and SparseTree.isAncestorEq (-> IsAncestorEq) Updates #35277 Change-Id: I7b53c9bd38ba384a3794386dd0eb94e4cbde4eb1 Reviewed-on: https://go-review.googlesource.com/c/go/+/204802 Run-TryBot: Dan Scales <firstname.lastname@example.org> TryBot-Result: Gobot Gobot <email@example.com> Reviewed-by: Keith Randall <firstname.lastname@example.org>