On Mon, Nov 17, 2025 at 3:03 PM Andrew Pillar <[email protected]> wrote: > > Came across this interesting problem when writing some database query > code. In summary, I wrote a function that took an interface, uses > reflect to get the struct fields from it and uses these to build up a > slice of destination values which would then be given to > database.sql.Rows.Scan. These values would be structs which implement > the sql.Scanner interface, what with their implementations using > reflect to set the value on the original struct fields. > > When testing this implementation I was passing through a struct with > unexported fields, typically I would expect this to panic, as calls to > reflect.Value.Set will panic if the value cannot be set, which > unexported fields can't be. Further debugging lead me to noticing that > the call to panic causes the main goroutine to block indefinitely. > > I have managed to replicate the issue in under 100 lines of code, but > this is something I have not encountered before and my searches for > "panic calls block goroutine" or such similar queries have yielded no > results for the issue I am experiencing. > > The code for the replicated issue can be found here: > https://go.dev/play/p/15M8kS7i9lg > > The above code has changed somewhat from the original code I had in > place for simplicites sake. On line 28 where it calls panic directly, > the original code I had instead had a call to reflect.Value.Set, which > would panic if the value could not be set. The Go playground won't be > able to run it as it times out due to the dependency on > modernc.org/sqlite (and even if it did build, the goroutine blocks > indefinitely so it won't run anyway). > > I do have a workaround in place for what I'm trying to achieve, but the > question I have about this remains: Why is the call to panic blocking > the main goroutine and preventing the program from exiting?
If you hit ^\ (on a Unix system) you will get a stack backtrace from a hung program. In this case you will see that the program is hanging in the deferred call to db.Close in your main function. The Rows Scan method is acquiring a lock, and db.Close is trying to get the same lock, but nothing has released the lock. So your program is deadlocked. Ian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcWB6rcoq-%2BRsPN5WzaEjUprm7oXyzs9zUU%2BMJ3e6PDHGQ%40mail.gmail.com.
