{"action":"created","issue":{"url":"https://api.github.com/repos/golang/go/issues/12528","labels_url":"https://api.github.com/repos/golang/go/issues/12528/labels{/name}","comments_url":"https://api.github.com/repos/golang/go/issues/12528/comments","events_url":"https://api.github.com/repos/golang/go/issues/12528/events","html_url":"https://github.com/golang/go/issues/12528","id":105159428,"number":12528,"title":"runtime: stack barrier inconsistency during profiling (dup #12932?)","user":{"login":"vsdutka","id":12748113,"avatar_url":"https://avatars.githubusercontent.com/u/12748113?v=3","gravatar_id":"","url":"https://api.github.com/users/vsdutka","html_url":"https://github.com/vsdutka","followers_url":"https://api.github.com/users/vsdutka/followers","following_url":"https://api.github.com/users/vsdutka/following{/other_user}","gists_url":"https://api.github.com/users/vsdutka/gists{/gist_id}","starred_url":"https://api.github.com/users/vsdutka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vsdutka/subscriptions","organizations_url":"https://api.github.com/users/vsdutka/orgs","repos_url":"https://api.github.com/users/vsdutka/repos","events_url":"https://api.github.com/users/vsdutka/events{/privacy}","received_events_url":"https://api.github.com/users/vsdutka/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/golang/go/milestones/33","html_url":"https://github.com/golang/go/milestones/Go1.5.3","labels_url":"https://api.github.com/repos/golang/go/milestones/33/labels","id":1424254,"number":33,"title":"Go1.5.3","description":"Go 1.5.3, if that happens.\r\n","creator":{"login":"rsc","id":104030,"avatar_url":"https://avatars.githubusercontent.com/u/104030?v=3","gravatar_id":"","url":"https://api.github.com/users/rsc","html_url":"https://github.com/rsc","followers_url":"https://api.github.com/users/rsc/followers","following_url":"https://api.github.com/users/rsc/following{/other_user}","gists_url":"https://api.github.com/users/rsc/gists{/gist_id}","starred_url":"https://api.github.com/users/rsc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rsc/subscriptions","organizations_url":"https://api.github.com/users/rsc/orgs","repos_url":"https://api.github.com/users/rsc/repos","events_url":"https://api.github.com/users/rsc/events{/privacy}","received_events_url":"https://api.github.com/users/rsc/received_events","type":"User","site_admin":false},"open_issues":1,"closed_issues":1,"state":"open","created_at":"2015-11-23T04:56:48Z","updated_at":"2015-12-12T06:47:24Z","due_on":"2016-01-30T05:00:00Z","closed_at":null},"comments":47,"created_at":"2015-09-07T07:07:24Z","updated_at":"2015-12-17T23:29:54Z","closed_at":null,"body":"I started to give error \"writebarrierptr_nostore1\" without any stack after compilation of my app \"https://github.com/vsdutka/iplsgo\" with Go 1.5 and stress it by 400 concurent requests.\r\n\r\nOS: Windows Server 2008 R2 Standart 64bit"},"comment":{"url":"https://api.github.com/repos/golang/go/issues/comments/165614903","html_url":"https://github.com/golang/go/issues/12528#issuecomment-165614903","issue_url":"https://api.github.com/repos/golang/go/issues/12528","id":165614903,"user":{"login":"aclements","id":2688315,"avatar_url":"https://avatars.githubusercontent.com/u/2688315?v=3","gravatar_id":"","url":"https://api.github.com/users/aclements","html_url":"https://github.com/aclements","followers_url":"https://api.github.com/users/aclements/followers","following_url":"https://api.github.com/users/aclements/following{/other_user}","gists_url":"https://api.github.com/users/aclements/gists{/gist_id}","starred_url":"https://api.github.com/users/aclements/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aclements/subscriptions","organizations_url":"https://api.github.com/users/aclements/orgs","repos_url":"https://api.github.com/users/aclements/repos","events_url":"https://api.github.com/users/aclements/events{/privacy}","received_events_url":"https://api.github.com/users/aclements/received_events","type":"User","site_admin":false},"created_at":"2015-12-17T23:29:54Z","updated_at":"2015-12-17T23:29:54Z","body":"I went through every (non-testing) use of gentraceback and every place that modifies stkbar or stkbarPos to root out remaining races:\r\n\r\n<table>\r\n <tr><td></td><td colspan=\"5\">stkbar/stkbarPos write</td></tr>\r\n <tr><td>gentraceback caller</td>\r\n     <th>stackBarrier (sync)</th>\r\n     <th>gcUnwindBarriers (stack lock + sync)</tg>\r\n     <th>setNextBarrierPC (sync)</th>\r\n     <th>copystack (stack lock + sync)</th>\r\n     <th>scanstack (stack lock + safe point)</th></tr>\r\n <tr><td>dumpgoroutine (STW)</td><td colspan=\"5\" rowspan=\"2\" align=\"center\">STW</td></tr>\r\n <tr><td>saveg (STW)</td></tr>\r\n <tr><td>callers/gcallers (sync)</td><td colspan=\"4\" rowspan=\"5\" align=\"center\">sync</td><td>sync</td></tr>\r\n <tr><td>copystack (stack lock + safe point)</td><td>stack lock</td></tr>\r\n <tr><td>scanstack (stack lock + safe point)</td><td>stack lock</td></tr>\r\n <tr><td>sigprof cgo (safe point)</td><td><b>UNSAFE</b></td></tr>\r\n <tr><td>sigprof libcall (safe point)</td><td><b>UNSAFE</b></td></tr>\r\n <tr><td>sigprof user (stack lock)</td><td>gtb fixup</td><td>stack lock</td><td><b>UNSAFE</b></td><td>stack lock</td><td>stack lock</td></tr>\r\n</table>\r\n\r\nThere are four labels on functions above: \"STW\" means the function stops the world, \"stack lock\" means that the function holds the stack lock while reading or writing stkbar, \"safe point\" means the function ensures the G is at a safe point, and \"sync\" means the function is running synchronously on the G and preventing safe points. Two \"stack lock\" functions are safe because they serialize on the lock. Two \"sync\" functions are safe because they cannot both be running on the G at the same time. A \"sync\" and a \"safe point\" function are safe because the sync function prevents the G from reaching a safe point, and the safe point function prevents the G from entering a sync function.\r\n\r\nFor each reader/writer pair, I've written what synchronizes them, if anything. In many cases there are multiple things that synchronize them, in which case I've picked one to simplify the table.\r\n\r\nThis shows that we still have three problems in profiling signals (two of which are essentially the same), and a frustrating level of complexity.\r\n\r\nI plan to make two changes to address these:\r\n\r\n1. Disallow cgo and libcall tracebacks in sigprof if it fails to acquire the stack barrier lock.\r\n2. Make setNextBarrierPC acquire the stack barrier lock.\r\n\r\nThis should simplify the synchronization down to:\r\n\r\n<table>\r\n <tr><td></td><td colspan=\"5\">stkbar/stkbarPos write</td></tr>\r\n <tr><td>gentraceback caller</td>\r\n     <th>stackBarrier (sync)</th>\r\n     <th>gcUnwindBarriers (stack lock + sync)</tg>\r\n     <th>setNextBarrierPC (stack lock + sync)</th>\r\n     <th>copystack (stack lock + sync)</th>\r\n     <th>scanstack (stack lock + safe point)</th></tr>\r\n <tr><td>dumpgoroutine (STW)</td><td colspan=\"5\" rowspan=\"2\" align=\"center\">STW</td></tr>\r\n <tr><td>saveg (STW)</td></tr>\r\n <tr><td>callers/gcallers (sync)</td><td colspan=\"5\">sync</td></tr>\r\n <tr><td>scanstack (stack lock + safe point)</td><td rowspan=\"4\">sync</td><td colspan=\"4\" rowspan=\"5\">stack lock</td></tr>\r\n <tr><td>copystack (stack lock + safe point)</td></tr>\r\n <tr><td>sigprof cgo (stack lock + safe point)</td></tr>\r\n <tr><td>sigprof libcall (stack lock + safe point)</td></tr>\r\n <tr><td>sigprof user (stack lock)</td><td>gtb fixup</td></tr>\r\n</table>\r\n"}}