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.

Reply via email to