From bfeda9188a054efdb950c9c9727d6bce7ad04961 Mon Sep 17 00:00:00 2001 From: Russ Cox <rsc@golang.org> Date: Wed, 14 Jan 2015 14:57:10 -0500 Subject: [PATCH] runtime: fix accounting race in printlock It could happen that mp.printlock++ happens, then on entry to lock, the goroutine is preempted and then rescheduled onto another m for the actual call to lock. Now the lock and the printlock++ have happened on different m's. This can lead to printlock not being unlocked, which either gives a printing deadlock or a crash when the goroutine reschedules, because m.locks > 0. Change-Id: Ib0c08740e1b53de3a93f7ebf9b05f3dceff48b9f Reviewed-on: https://go-review.googlesource.com/2819 Reviewed-by: Rick Hudson <rlh@golang.org> --- src/runtime/print1.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/runtime/print1.go b/src/runtime/print1.go index 7bec5599b5..e717c98799 100644 --- a/src/runtime/print1.go +++ b/src/runtime/print1.go @@ -53,10 +53,12 @@ var debuglock mutex func printlock() { mp := getg().m + mp.locks++ // do not reschedule between printlock++ and lock(&debuglock). mp.printlock++ if mp.printlock == 1 { lock(&debuglock) } + mp.locks-- // now we know debuglock is held and holding up mp.locks for us. } func printunlock() { -- 2.30.9