]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: do not omit stack trace of goroutine that handles async events
authorRichard Musiol <mail@richard-musiol.de>
Sun, 6 Oct 2019 20:39:08 +0000 (22:39 +0200)
committerRichard Musiol <neelance@gmail.com>
Mon, 7 Oct 2019 18:13:27 +0000 (18:13 +0000)
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 <neelance@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/internal/objabi/funcid.go
src/runtime/lock_js.go
src/runtime/symtab.go
src/runtime/traceback.go

index a30bc3fa05a6c9fda464d44f8a0c0fc1ae3dee5a..fe54eba663183e3c03d5019c4e938faa12a5bc60 100644 (file)
@@ -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 == "<autogenerated>" {
                return FuncID_wrapper
index c038499f2a9d34eef83f43c03e24964db2582c4b..d08238ce3cf4f853b82bf412ccc13cd9bd15a1b4 100644 (file)
@@ -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.
index 367e06003ae23da69e20f1790dcfc60c35b2478d..8296a8590dbb827cc39f98a0cf94b9168327f07e 100644 (file)
@@ -253,6 +253,7 @@ const (
        funcID_debugCallV1
        funcID_gopanic
        funcID_panicwrap
+       funcID_handleAsyncEvents
        funcID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.)
 )
 
index ef48c9fa1f9b888acee43185599a3c2e30ed7b44..5153390f1db647eb1f10f51e2a80a9e83e1ff88a 100644 (file)
@@ -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 {