Expecting "all goroutines are asleep" but instead program just hangs


(Eduard Bardají Puig) #1

I’ve accidentally created what I believe is a deadlock, and I was expecting to get the “all goroutines are asleep” error, but instead it just hangs indefinitedly. I thought it could be because I have another goroutine running, but it seems that’s not the case ( runtime.NumGoroutine() prints 1 just before the supposed deadlock).

I’d really appreciate some help debugging the app, a very small condensed version is in this reproduction repo: https://gitlab.com/aryzing/repro-go-deadlock

Other things I’ve tried include

  • Making sure that none of the dependencies start goroutines that may be running in the background, playground
  • Setting up pproc in the with-profiling branch in the repo above, but can’t get any output into either cpu.prof or mem.prof.

Note: I know how to fix the issue. That’s not what I’m asking here. I’m asking why the go runtime does not report a deadlock.


(Johan Dahl) #2

examiner.InitExaminer() mustn’t it run before examiner.Supervise? Otherwise is there nothing which reads from the channel? Should be a deadlock thou.


(Sean Killian) #3

This is fascinating me. I’m able to reproduce this with this however you have to download it and run it locally! It doesn’t deadlock in the playground!

I still don’t know what’s going on, but one difference I noticed was that when I run this locally, the call to examiner.Supervise has 3 parameters: The []*q.Q slice’s Data, Len and Cap:

gitlab.com/aryzing/repro-go-deadlock/examiner.Supervise(0xc420010c00, 0x2, 0x2)

But in the stack trace in my little reproduceable scenario on the playground, there’s a 4th parameter:

main.Supervise(0x85efa4, 0x3, 0x3, 0x1b10)

I’m not sure why or if that’s even relevant at all.

Still looking into it…


(Sean Killian) #4

OK, if I comment out _ "net/http/pprof", the deadlock is identified.


(Eduard Bardají Puig) #5

Thanks for the deep dive! I’m not quite sure how commenting out that import helps identify the lack of a deadlock error. On the master branch there’s no use of pprof, and the app never errors out. On the with-profiling branch, even after commenting out "net/http/pprof" the app does not report a deadlock error.

I’m on go version go1.12.7 linux/amd64


(Sean Killian) #6

@aryzing This seems to be from an old version of Go, but it might still be relevant: https://github.com/golang/go/issues/12734


(Eduard Bardají Puig) #7

Good find! Perhaps this should be documented better :slight_smile: thanks for all the help!