From: Richard Musiol Date: Sun, 6 Oct 2019 20:39:08 +0000 (+0200) Subject: runtime: do not omit stack trace of goroutine that handles async events X-Git-Tag: go1.14beta1~834 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1c8e6077f67ea33b752ebf93483517b03ad9393f;p=gostls13.git runtime: do not omit stack trace of goroutine that handles async events On wasm there is a special goroutine that handles asynchronous events. Blocking this goroutine often causes a deadlock. However, the stack trace of this goroutine was omitted when printing the deadlock error. This change adds an exception so the goroutine is not considered as an internal system goroutine and the stack trace gets printed, which helps with debugging the deadlock. Updates #32764 Change-Id: Icc8f5ba3ca5a485d557b7bdd76bf2f1ffb92eb3e Reviewed-on: https://go-review.googlesource.com/c/go/+/199537 Run-TryBot: Richard Musiol TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- diff --git a/src/cmd/internal/objabi/funcid.go b/src/cmd/internal/objabi/funcid.go index a30bc3fa05..fe54eba663 100644 --- a/src/cmd/internal/objabi/funcid.go +++ b/src/cmd/internal/objabi/funcid.go @@ -37,6 +37,7 @@ const ( FuncID_debugCallV1 FuncID_gopanic FuncID_panicwrap + FuncID_handleAsyncEvents FuncID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.) ) @@ -82,6 +83,8 @@ func GetFuncID(name, file string) FuncID { return FuncID_gopanic case "runtime.panicwrap": return FuncID_panicwrap + case "runtime.handleAsyncEvents": + return FuncID_handleAsyncEvents } if file == "" { return FuncID_wrapper diff --git a/src/runtime/lock_js.go b/src/runtime/lock_js.go index c038499f2a..d08238ce3c 100644 --- a/src/runtime/lock_js.go +++ b/src/runtime/lock_js.go @@ -149,16 +149,18 @@ var returnedEventHandler *g func init() { // At the toplevel we need an extra goroutine that handles asynchronous events. initg := getg() - go func() { - returnedEventHandler = getg() - goready(initg, 1) + go handleAsyncEvents(initg) + gopark(nil, nil, waitReasonZero, traceEvNone, 1) +} - gopark(nil, nil, waitReasonZero, traceEvNone, 1) - returnedEventHandler = nil +func handleAsyncEvents(initg *g) { + returnedEventHandler = getg() + goready(initg, 1) - pause(getcallersp() - 16) - }() gopark(nil, nil, waitReasonZero, traceEvNone, 1) + returnedEventHandler = nil + + pause(getcallersp() - 16) } // beforeIdle gets called by the scheduler if no goroutine is awake. diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go index 367e06003a..8296a8590d 100644 --- a/src/runtime/symtab.go +++ b/src/runtime/symtab.go @@ -253,6 +253,7 @@ const ( funcID_debugCallV1 funcID_gopanic funcID_panicwrap + funcID_handleAsyncEvents funcID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.) ) diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go index ef48c9fa1f..5153390f1d 100644 --- a/src/runtime/traceback.go +++ b/src/runtime/traceback.go @@ -997,8 +997,8 @@ func topofstack(f funcInfo, g0 bool) bool { // isSystemGoroutine reports whether the goroutine g must be omitted // in stack dumps and deadlock detector. This is any goroutine that -// starts at a runtime.* entry point, except for runtime.main and -// sometimes runtime.runfinq. +// starts at a runtime.* entry point, except for runtime.main, +// runtime.handleAsyncEvents (wasm only) and sometimes runtime.runfinq. // // If fixed is true, any goroutine that can vary between user and // system (that is, the finalizer goroutine) is considered a user @@ -1009,7 +1009,7 @@ func isSystemGoroutine(gp *g, fixed bool) bool { if !f.valid() { return false } - if f.funcID == funcID_runtime_main { + if f.funcID == funcID_runtime_main || f.funcID == funcID_handleAsyncEvents { return false } if f.funcID == funcID_runfinq {