it's something like https://github.com/golang/go/issues/64498
Scan locks but doesn't always unlock when it returns,
which causes a deadlock with your deferred close which also tries to lock.

If you run it with CGO_ENABLED=0, you'll also get a nice deadlock report:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [sync.RWMutex.Lock]:
sync.runtime_SemacquireRWMutex(0x0?, 0x0?, 0x9d8f00?)
        runtime/sema.go:105 +0x25
sync.(*RWMutex).Lock(0x10?)
        sync/rwmutex.go:155 +0x6b
database/sql.(*Rows).close(0x235702c1e0a0, {0x0, 0x0})
        database/sql/sql.go:3452 +0xad
database/sql.(*Rows).Close(0x235702c1e0a0)
        database/sql/sql.go:3448 +0x26
panic({0x70f240?, 0x7a6910?})
        runtime/panic.go:856 +0x13a
main.(*field).Scan(0x9cb2d0?, {0x716700?, 0x0?})
        go.seankhliao.com/testrepo1314/main.go:28 +0x25
database/sql.convertAssignRows({0x716700, 0x235702c20050}, {0x70f400,
0x7b16d0}, 0x235702c1e0a0)
        database/sql/convert.go:394 +0x1fd9
database/sql.(*Rows).scanLocked(0x235702c1e0a0, {0x235702c32080, 0x4,
0x48e889?})
        database/sql/sql.go:3406 +0x38c
database/sql.(*Rows).Scan(0x235702c1e0a0, {0x235702c32080, 0x4, 0x7439bc?})
        database/sql/sql.go:3374 +0x73
main.main()
        go.seankhliao.com/testrepo1314/main.go:72 +0x535

goroutine 17 [select]:
database/sql.(*DB).connectionOpener(0x235702c90000, {0x7a7df8, 0x235702c8a000})
        database/sql/sql.go:1261 +0x89
created by database/sql.OpenDB in goroutine 1
        database/sql/sql.go:841 +0x145
exit status 2

- sean

- sean


On Mon, Nov 17, 2025 at 10:59 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?
>
> --
> 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/f1068b9389dccbd11c13e942a0bceaec2aada8f7.camel%40andrewpillar.com.

-- 
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/CAGabyPpMwnnFrJmVne%3DypVDxhOFeLzxe6EOqc0L6ZiRdSUL0%3DQ%40mail.gmail.com.

Reply via email to