[GH-ISSUE #211] HttpChunkedReader does not follow the ReadAt guidelines leading to the program getting stuck #139

Closed
opened 2026-02-28 14:25:43 +03:00 by kerem · 7 comments
Owner

Originally created by @tooxo on GitHub (Sep 16, 2025).
Original GitHub issue: https://github.com/devgianlu/go-librespot/issues/211

Reading the documentation for the ReaderAt interface, it states:

// When ReadAt returns n < len(p), it returns a non-nil error
// explaining why more bytes were not returned. In this respect,
// ReadAt is stricter than Read.

Looking at the implementation of ReadAt in the HttpChunkedReader:
github.com/devgianlu/go-librespot@8d888e4e46/audio/chunked_reader.go (L223-L225)

This case can (and does according to my debugger) return the tuple (0, nil), which is an illegal result value according to the documentation. I observed this, because this call

github.com/devgianlu/go-librespot@8d888e4e46/vorbis/decoder.go (L172)

never returned, blocking the entire program as well as the dealer loop.

I'm not entirely sure what the correct return value would be here, i would assume (n, io.EOF), but I would like some advice on this.

Core Dump
SIGTRAP: trace trap
PC=0x4839f8 m=2 sigcode=0
goroutine 0 gp=0x4000002a80 m=2 mp=0x4000060808 [idle]:
runtime.usleep(0x14)
        /usr/lib/go-1.25/src/runtime/sys_linux_arm64.s:139 +0x48 fp=0x7f3a6bc790 sp=0x7f3a6bc760 pc=0x4839f8
runtime.sysmon()
        /usr/lib/go-1.25/src/runtime/proc.go:6234 +0xd0 fp=0x7f3a6bc830 sp=0x7f3a6bc790 pc=0x455750
runtime.mstart1()
        /usr/lib/go-1.25/src/runtime/proc.go:1928 +0xa8 fp=0x7f3a6bc860 sp=0x7f3a6bc830 pc=0x44dd98
runtime.mstart0()
        /usr/lib/go-1.25/src/runtime/proc.go:1881 +0x68 fp=0x7f3a6bc890 sp=0x7f3a6bc860 pc=0x44dcc8
runtime.mstart()
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:179 +0x10 fp=0x7f3a6bc8a0 sp=0x7f3a6bc890 pc=0x480660
goroutine 1 gp=0x40000021c0 m=nil [select, 116 minutes]:
runtime.gopark(0xf2a768, 0x0, 0x9, 0x3, 0x1)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400078b540 sp=0x400078b510 pc=0x47b854
runtime.selectgo(0x400078b7d8, 0x40006936f8, 0x400000c900?, 0x0, 0x100?, 0x1)
        /usr/lib/go-1.25/src/runtime/select.go:351 +0x814 fp=0x400078b6a0 sp=0x400078b540 pc=0x45c2d4
github.com/devgianlu/go-librespot/zeroconf.(*Zeroconf).Serve(0x400032c140, 0x400078ba30)
        /home/pi/go-librespot/zeroconf/zeroconf.go:283 +0x258 fp=0x400078b870 sp=0x400078b6a0 pc=0xb82198
main.(*App).withAppPlayer(0x40001fa300, {0xf83ba8, 0x14e33a0}, 0x400003c690)
        /home/pi/go-librespot/cmd/daemon/main.go:323 +0x958 fp=0x400078bb40 sp=0x400078b870 pc=0xc289a8
main.(*App).Zeroconf(0x40001fa300, {0xf83ba8, 0x14e33a0})
        /home/pi/go-librespot/cmd/daemon/main.go:172 +0x8c fp=0x400078bba0 sp=0x400078bb40 pc=0xc2776c
main.main()
        /home/pi/go-librespot/cmd/daemon/main.go:562 +0x820 fp=0x400078bf60 sp=0x400078bba0 pc=0xc2b460
runtime.main()
        /usr/lib/go-1.25/src/runtime/proc.go:285 +0x218 fp=0x400078bfd0 sp=0x400078bf60 pc=0x44ad18
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400078bfd0 sp=0x400078bfd0 pc=0x482c04
goroutine 18 gp=0x4000092380 m=nil [force gc (idle), 11 minutes]:
runtime.gopark(0xf2a700, 0x14b9ac0, 0x11, 0xa, 0x1)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000056770 sp=0x4000056740 pc=0x47b854
runtime.goparkunlock(0x14b9ac0?, 0x0?, 0x0?, 0x0?)
        /usr/lib/go-1.25/src/runtime/proc.go:466 +0x34 fp=0x40000567a0 sp=0x4000056770 pc=0x44b194
runtime.forcegchelper()
        /usr/lib/go-1.25/src/runtime/proc.go:373 +0xb0 fp=0x40000567d0 sp=0x40000567a0 pc=0x44b060
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40000567d0 sp=0x40000567d0 pc=0x482c04
created by runtime.init.7 in goroutine 1
        /usr/lib/go-1.25/src/runtime/proc.go:361 +0x24
goroutine 19 gp=0x4000092540 m=nil [runnable]:
runtime.goschedIfBusy()
        /usr/lib/go-1.25/src/runtime/proc.go:412 +0x34 fp=0x4000056f70 sp=0x4000056f50 pc=0x44b144
runtime.bgsweep(0x40000a2000)
        /usr/lib/go-1.25/src/runtime/mgcsweep.go:308 +0x164 fp=0x4000056fb0 sp=0x4000056f70 pc=0x434c04
runtime.gcenable.gowrap1()
        /usr/lib/go-1.25/src/runtime/mgc.go:212 +0x28 fp=0x4000056fd0 sp=0x4000056fb0 pc=0x428e88
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000056fd0 sp=0x4000056fd0 pc=0x482c04
created by runtime.gcenable in goroutine 1
        /usr/lib/go-1.25/src/runtime/mgc.go:212 +0x6c
goroutine 20 gp=0x4000092700 m=nil [GC scavenge wait]:
runtime.gopark(0xf2a700, 0x14bb900, 0xd, 0xa, 0x2)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000057720 sp=0x40000576f0 pc=0x47b854
runtime.goparkunlock(0x14bb900?, 0x0?, 0x0?, 0x0?)
        /usr/lib/go-1.25/src/runtime/proc.go:466 +0x34 fp=0x4000057750 sp=0x4000057720 pc=0x44b194
runtime.(*scavengerState).park(0x14bb900)
        /usr/lib/go-1.25/src/runtime/mgcscavenge.go:425 +0x4c fp=0x4000057780 sp=0x4000057750 pc=0x43232c
runtime.bgscavenge(0x40000a2000)
        /usr/lib/go-1.25/src/runtime/mgcscavenge.go:658 +0x60 fp=0x40000577b0 sp=0x4000057780 pc=0x432870
runtime.gcenable.gowrap2()
        /usr/lib/go-1.25/src/runtime/mgc.go:213 +0x28 fp=0x40000577d0 sp=0x40000577b0 pc=0x428e28
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40000577d0 sp=0x40000577d0 pc=0x482c04
created by runtime.gcenable in goroutine 1
        /usr/lib/go-1.25/src/runtime/mgc.go:213 +0xac
goroutine 2 gp=0x4000003340 m=nil [finalizer wait, 38 minutes]:
runtime.gopark(0xf2a440, 0x14e35d8, 0x10, 0xa, 0x1)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400051bd80 sp=0x400051bd50 pc=0x47b854
runtime.runFinalizers()
        /usr/lib/go-1.25/src/runtime/mfinal.go:210 +0xec fp=0x400051bfd0 sp=0x400051bd80 pc=0x427fbc
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400051bfd0 sp=0x400051bfd0 pc=0x482c04
created by runtime.createfing in goroutine 1
        /usr/lib/go-1.25/src/runtime/mfinal.go:172 +0x4c
goroutine 21 gp=0x4000093c00 m=nil [cleanup wait, 31 minutes]:
runtime.gopark(0xf2a700, 0x14bbfe0, 0x2e, 0xa, 0x1)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400006df20 sp=0x400006def0 pc=0x47b854
runtime.goparkunlock(0x14bbfe8?, 0x4b?, 0x0?, 0x400006df88?)
        /usr/lib/go-1.25/src/runtime/proc.go:466 +0x34 fp=0x400006df50 sp=0x400006df20 pc=0x44b194
runtime.(*cleanupQueue).dequeue(0x14bbe60)
        /usr/lib/go-1.25/src/runtime/mcleanup.go:439 +0xa0 fp=0x400006df90 sp=0x400006df50 pc=0x424ea0
runtime.runCleanups()
        /usr/lib/go-1.25/src/runtime/mcleanup.go:635 +0x60 fp=0x400006dfd0 sp=0x400006df90 pc=0x425670
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400006dfd0 sp=0x400006dfd0 pc=0x482c04
created by runtime.(*cleanupQueue).createGs in goroutine 1
        /usr/lib/go-1.25/src/runtime/mcleanup.go:589 +0xb0
goroutine 7 gp=0x400031a1c0 m=nil [GC worker (idle), 11 minutes]:
runtime.gopark(0xf2a458, 0x4000308600, 0x1c, 0xa, 0x0)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40002e0f00 sp=0x40002e0ed0 pc=0x47b854
runtime.gcBgMarkWorker(0x4000181500)
        /usr/lib/go-1.25/src/runtime/mgc.go:1463 +0xdc fp=0x40002e0fb0 sp=0x40002e0f00 pc=0x42ab7c
runtime.gcBgMarkStartWorkers.gowrap1()
        /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x28 fp=0x40002e0fd0 sp=0x40002e0fb0 pc=0x42aa48
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40002e0fd0 sp=0x40002e0fd0 pc=0x482c04
created by runtime.gcBgMarkStartWorkers in goroutine 23
        /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x6c
goroutine 8 gp=0x400031ae00 m=nil [GC worker (idle), 11 minutes]:
runtime.gopark(0xf2a458, 0x4000308800, 0x1c, 0xa, 0x0)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000070f00 sp=0x4000070ed0 pc=0x47b854
runtime.gcBgMarkWorker(0x4000181500)
        /usr/lib/go-1.25/src/runtime/mgc.go:1463 +0xdc fp=0x4000070fb0 sp=0x4000070f00 pc=0x42ab7c
runtime.gcBgMarkStartWorkers.gowrap1()
        /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x28 fp=0x4000070fd0 sp=0x4000070fb0 pc=0x42aa48
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000070fd0 sp=0x4000070fd0 pc=0x482c04
created by runtime.gcBgMarkStartWorkers in goroutine 23
        /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x6c
goroutine 9 gp=0x400031afc0 m=nil [GC worker (idle)]:
runtime.gopark(0xf2a458, 0x4000308a00, 0x1c, 0xa, 0x0)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400051af00 sp=0x400051aed0 pc=0x47b854
runtime.gcBgMarkWorker(0x4000181500)
        /usr/lib/go-1.25/src/runtime/mgc.go:1463 +0xdc fp=0x400051afb0 sp=0x400051af00 pc=0x42ab7c
runtime.gcBgMarkStartWorkers.gowrap1()
        /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x28 fp=0x400051afd0 sp=0x400051afb0 pc=0x42aa48
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400051afd0 sp=0x400051afd0 pc=0x482c04
created by runtime.gcBgMarkStartWorkers in goroutine 23
        /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x6c
goroutine 10 gp=0x400031b180 m=nil [GC worker (idle)]:
runtime.gopark(0xf2a458, 0x4000308c00, 0x1c, 0xa, 0x0)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40002e3f00 sp=0x40002e3ed0 pc=0x47b854
runtime.gcBgMarkWorker(0x4000181500)
        /usr/lib/go-1.25/src/runtime/mgc.go:1463 +0xdc fp=0x40002e3fb0 sp=0x40002e3f00 pc=0x42ab7c
runtime.gcBgMarkStartWorkers.gowrap1()
        /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x28 fp=0x40002e3fd0 sp=0x40002e3fb0 pc=0x42aa48
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40002e3fd0 sp=0x40002e3fd0 pc=0x482c04
created by runtime.gcBgMarkStartWorkers in goroutine 23
        /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x6c
goroutine 37 gp=0x4000392540 m=nil [chan receive, 518 minutes]:
runtime.gopark(0xf2a3e8, 0x40004f8148, 0xe, 0x7, 0x2)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400005de70 sp=0x400005de40 pc=0x47b854
runtime.chanrecv(0x40004f80e0, 0x400005df88, 0x1)
        /usr/lib/go-1.25/src/runtime/chan.go:667 +0x2c8 fp=0x400005def0 sp=0x400005de70 pc=0x417e78
runtime.chanrecv2(0x400003c680?, 0x0?)
        /usr/lib/go-1.25/src/runtime/chan.go:514 +0x14 fp=0x400005df20 sp=0x400005def0 pc=0x417b94
main.(*App).withAppPlayer.func1()
        /home/pi/go-librespot/cmd/daemon/main.go:270 +0x74 fp=0x400005dfd0 sp=0x400005df20 pc=0xc29774
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400005dfd0 sp=0x400005dfd0 pc=0x482c04
created by main.(*App).withAppPlayer in goroutine 1
        /home/pi/go-librespot/cmd/daemon/main.go:267 +0x760
goroutine 38 gp=0x4000392700 m=nil [chan receive, 285 minutes]:
runtime.gopark(0xf2a3e8, 0x40001800d8, 0xe, 0x7, 0x2)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40005a4dc0 sp=0x40005a4d90 pc=0x47b854
runtime.chanrecv(0x4000180070, 0x4000edffa8, 0x1)
        /usr/lib/go-1.25/src/runtime/chan.go:667 +0x2c8 fp=0x40005a4e40 sp=0x40005a4dc0 pc=0x417e78
runtime.chanrecv2(0x400032c140?, 0x0?)
        /usr/lib/go-1.25/src/runtime/chan.go:514 +0x14 fp=0x40005a4e70 sp=0x40005a4e40 pc=0x417b94
main.(*App).withAppPlayer.func2()
        /home/pi/go-librespot/cmd/daemon/main.go:286 +0x80 fp=0x40005a4fd0 sp=0x40005a4e70 pc=0xc292a0
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40005a4fd0 sp=0x40005a4fd0 pc=0x482c04
created by main.(*App).withAppPlayer in goroutine 1
        /home/pi/go-librespot/cmd/daemon/main.go:283 +0x8d4
goroutine 11 gp=0x40002ae8c0 m=nil [IO wait]:
runtime.gopark(0xf2a6e0, 0x7f39e74620, 0x2, 0x2, 0x5)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40003177d0 sp=0x40003177a0 pc=0x47b854
runtime.netpollblock(0x7f39e74600, 0x72, 0x0)
        /usr/lib/go-1.25/src/runtime/netpoll.go:575 +0xb8 fp=0x4000317810 sp=0x40003177d0 pc=0x443b58
internal/poll.runtime_pollWait(0x7f39e74600, 0x72)
        /usr/lib/go-1.25/src/runtime/netpoll.go:351 +0x48 fp=0x4000317830 sp=0x4000317810 pc=0x47ad18
internal/poll.(*pollDesc).wait(0x40000fa6a0, 0x72, 0x0)
        /usr/lib/go-1.25/src/internal/poll/fd_poll_runtime.go:84 +0x84 fp=0x4000317880 sp=0x4000317830 pc=0x535e14
internal/poll.(*pollDesc).waitRead(0x40000fa6a0, 0x0)
        /usr/lib/go-1.25/src/internal/poll/fd_poll_runtime.go:89 +0x38 fp=0x40003178d0 sp=0x4000317880 pc=0x535e98
internal/poll.(*FD).RawRead(0x40000fa680, 0x40008a4b90)
        /usr/lib/go-1.25/src/internal/poll/fd_unix.go:710 +0x180 fp=0x40003179a0 sp=0x40003178d0 pc=0x53c470
net.(*rawConn).Read(0x400005e0a8, 0x40008a4b90)
        /usr/lib/go-1.25/src/net/rawconn.go:44 +0x58 fp=0x4000317a20 sp=0x40003179a0 pc=0x5f7618
golang.org/x/net/internal/socket.(*Conn).recvMsg(0x40000a01a0, 0x400033be00, 0x0)
        /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/internal/socket/rawconn_msg.go:27 +0x2b8 fp=0x4000317ac0 sp=0x4000317a20 pc=0xafc938
golang.org/x/net/internal/socket.(*Conn).RecvMsg(0x40000a01a0, 0x400033be00, 0x0)
        /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/internal/socket/socket.go:247 +0x3c fp=0x4000317b10 sp=0x4000317ac0 pc=0xafdd9c
golang.org/x/net/ipv4.(*payloadHandler).ReadFrom(0x4000342150, {0x4000420000, 0x10000, 0x10000})
        /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/ipv4/payload_cmsg.go:31 +0x29c fp=0x4000317df0 sp=0x4000317b10 pc=0xb026ac
github.com/grandcat/zeroconf.(*Server).recv4(0x400033a0c0, 0x4000342140)
        /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:254 +0x150 fp=0x4000317fa0 sp=0x4000317df0 pc=0xb7b3f0
github.com/grandcat/zeroconf.(*Server).mainloop.gowrap1()
        /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:188 +0x38 fp=0x4000317fd0 sp=0x4000317fa0 pc=0xb7afd8
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000317fd0 sp=0x4000317fd0 pc=0x482c04
created by github.com/grandcat/zeroconf.(*Server).mainloop in goroutine 35
        /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:188 +0xcc
goroutine 12 gp=0x40002aea80 m=nil [runnable]:
runtime.(*_panic).start(0x40002ef920, 0x53c438, 0x40002ef990)
        /usr/lib/go-1.25/src/runtime/panic.go:809 +0x1b4 fp=0x40002ef900 sp=0x40002ef900 pc=0x4476e4
runtime.deferreturn()
        /usr/lib/go-1.25/src/runtime/panic.go:583 +0x50 fp=0x40002ef990 sp=0x40002ef900 pc=0x4470e0
internal/poll.(*FD).RawRead(0x40000fa780, 0x40005fdc70)
        /usr/lib/go-1.25/src/internal/poll/fd_unix.go:714 +0x148 fp=0x40002efa60 sp=0x40002ef990 pc=0x53c438
net.(*rawConn).Read(0x400005e0d0, 0x40005fdc70)
        /usr/lib/go-1.25/src/net/rawconn.go:44 +0x58 fp=0x40002efae0 sp=0x40002efa60 pc=0x5f7618
golang.org/x/net/internal/socket.(*Conn).recvMsg(0x40000a01c0, 0x40004f2ae0, 0x0)
        /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/internal/socket/rawconn_msg.go:27 +0x2b8 fp=0x40002efb80 sp=0x40002efae0 pc=0xafc938
golang.org/x/net/internal/socket.(*Conn).RecvMsg(0x40000a01c0, 0x40004f2ae0, 0x0)
        /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/internal/socket/socket.go:247 +0x3c fp=0x40002efbd0 sp=0x40002efb80 pc=0xafdd9c
golang.org/x/net/ipv6.(*payloadHandler).ReadFrom(0x40003421a0, {0x4000410000, 0x10000, 0x10000})
        /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/ipv6/payload_cmsg.go:31 +0x248 fp=0x40002efdf0 sp=0x40002efbd0 pc=0xb079b8
github.com/grandcat/zeroconf.(*Server).recv6(0x400033a0c0, 0x4000342190)
        /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:282 +0x150 fp=0x40002effa0 sp=0x40002efdf0 pc=0xb7b6e0
github.com/grandcat/zeroconf.(*Server).mainloop.gowrap2()
        /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:191 +0x38 fp=0x40002effd0 sp=0x40002effa0 pc=0xb7af68
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40002effd0 sp=0x40002effd0 pc=0x482c04
created by github.com/grandcat/zeroconf.(*Server).mainloop in goroutine 35
        /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:191 +0x18c
goroutine 39 gp=0x40003928c0 m=nil [IO wait, 13 minutes]:
runtime.gopark(0xf2a6e0, 0x7f39e74820, 0x2, 0x2, 0x5)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40003134e0 sp=0x40003134b0 pc=0x47b854
runtime.netpollblock(0x7f39e74800, 0x72, 0x0)
        /usr/lib/go-1.25/src/runtime/netpoll.go:575 +0xb8 fp=0x4000313520 sp=0x40003134e0 pc=0x443b58
internal/poll.runtime_pollWait(0x7f39e74800, 0x72)
        /usr/lib/go-1.25/src/runtime/netpoll.go:351 +0x48 fp=0x4000313540 sp=0x4000313520 pc=0x47ad18
internal/poll.(*pollDesc).wait(0x40000fa320, 0x72, 0x0)
        /usr/lib/go-1.25/src/internal/poll/fd_poll_runtime.go:84 +0x84 fp=0x4000313590 sp=0x4000313540 pc=0x535e14
internal/poll.(*pollDesc).waitRead(0x40000fa320, 0x0)
        /usr/lib/go-1.25/src/internal/poll/fd_poll_runtime.go:89 +0x38 fp=0x40003135e0 sp=0x4000313590 pc=0x535e98
internal/poll.(*FD).Accept(0x40000fa300)
        /usr/lib/go-1.25/src/internal/poll/fd_unix.go:613 +0x364 fp=0x4000313850 sp=0x40003135e0 pc=0x53b5e4
net.(*netFD).accept(0x40000fa300)
        /usr/lib/go-1.25/src/net/fd_unix.go:161 +0x58 fp=0x40003139f0 sp=0x4000313850 pc=0x5dab18
net.(*TCPListener).accept(0x4000468300)
        /usr/lib/go-1.25/src/net/tcpsock_posix.go:159 +0x4c fp=0x4000313ae0 sp=0x40003139f0 pc=0x5fef3c
net.(*TCPListener).Accept(0x4000468300)
        /usr/lib/go-1.25/src/net/tcpsock.go:380 +0x58 fp=0x4000313b90 sp=0x4000313ae0 pc=0x5fd268
net/http.(*onceCloseListener).Accept(0x400032a750)
        <autogenerated>:1 +0x60 fp=0x4000313c10 sp=0x4000313b90 pc=0x821c00
net/http.(*Server).Serve(0x40001fa600, {0xf82a90, 0x4000468300})
        /usr/lib/go-1.25/src/net/http/server.go:3463 +0x3a4 fp=0x4000313ef0 sp=0x4000313c10 pc=0x7eb8b4
net/http.Serve({0xf82a90, 0x4000468300}, {0xf79fe8, 0x400019a000})
        /usr/lib/go-1.25/src/net/http/server.go:2971 +0xe0 fp=0x4000313f50 sp=0x4000313ef0 pc=0x7ea580
github.com/devgianlu/go-librespot/zeroconf.(*Zeroconf).Serve.func2()
        /home/pi/go-librespot/zeroconf/zeroconf.go:280 +0x58 fp=0x4000313fd0 sp=0x4000313f50 pc=0xb822b8
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000313fd0 sp=0x4000313fd0 pc=0x482c04
created by github.com/devgianlu/go-librespot/zeroconf.(*Zeroconf).Serve in goroutine 1
        /home/pi/go-librespot/zeroconf/zeroconf.go:280 +0x1b8
goroutine 2579448 gp=0x4000949180 m=nil [chan receive, 32 minutes]:
runtime.gopark(0xf2a3e8, 0x400039c0d8, 0xe, 0x7, 0x2)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400078f740 sp=0x400078f710 pc=0x47b854
runtime.chanrecv(0x400039c070, 0x4000041837, 0x1)
        /usr/lib/go-1.25/src/runtime/chan.go:667 +0x2c8 fp=0x400078f7c0 sp=0x400078f740 pc=0x417e78
runtime.chanrecv1(0x4000201180?, 0x0?)
        /usr/lib/go-1.25/src/runtime/chan.go:509 +0x14 fp=0x400078f7f0 sp=0x400078f7c0 pc=0x417b74
github.com/devgianlu/go-librespot/dealer.(*Dealer).handleRequest(0x40001be540, 0x400026a000)
        /home/pi/go-librespot/dealer/recv.go:237 +0x3fc fp=0x400078fc60 sp=0x400078f7f0 pc=0xae1b6c
github.com/devgianlu/go-librespot/dealer.(*Dealer).recvLoop(0x40001be540)
        /home/pi/go-librespot/dealer/dealer.go:213 +0x9f0 fp=0x400078ffb0 sp=0x400078fc60 pc=0xadfc40
github.com/devgianlu/go-librespot/dealer.(*Dealer).startReceiving.func1.gowrap1()
        /home/pi/go-librespot/dealer/dealer.go:125 +0x2c fp=0x400078ffd0 sp=0x400078ffb0 pc=0xadeddc
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400078ffd0 sp=0x400078ffd0 pc=0x482c04
created by github.com/devgianlu/go-librespot/dealer.(*Dealer).startReceiving.func1 in goroutine 2579422
        /home/pi/go-librespot/dealer/dealer.go:125 +0xb0
goroutine 2579422 gp=0x400057fa40 m=nil [chan receive, 32 minutes]:
runtime.gopark(0xf2a3e8, 0x40001a84c8, 0xe, 0x7, 0x2)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000f50770 sp=0x4000f50740 pc=0x47b854
runtime.chanrecv(0x40001a8460, 0x4000f50878, 0x1)
        /usr/lib/go-1.25/src/runtime/chan.go:667 +0x2c8 fp=0x4000f507f0 sp=0x4000f50770 pc=0x417e78
runtime.chanrecv1(0xac8a1c?, 0x1?)
        /usr/lib/go-1.25/src/runtime/chan.go:509 +0x14 fp=0x4000f50820 sp=0x4000f507f0 pc=0x417b74
github.com/devgianlu/go-librespot/player.(*Player).PositionMs(0x40004c7500)
        /home/pi/go-librespot/player/player.go:408 +0x84 fp=0x4000f508b0 sp=0x4000f50820 pc=0xab5324
main.(*AppPlayer).skipNext(0x400035d880, {0xf83ba8, 0x14e33a0}, 0x0)
        /home/pi/go-librespot/cmd/daemon/controls.go:565 +0x68 fp=0x4000f50ab0 sp=0x4000f508b0 pc=0xc24018
main.(*AppPlayer).handlePlayerCommand(_, {_, _}, {0x54596ee3, {0x40000c84b0, 0x28}, {{0x4001186040, 0x9}, {0x0, 0x0}, ...}})
        /home/pi/go-librespot/cmd/daemon/player.go:313 +0x1c20 fp=0x4000f51130 sp=0x4000f50ab0 pc=0xc2e5a0
main.(*AppPlayer).handleDealerRequest(_, {_, _}, {0x400039c070, {0x40000c83f0, 0x24}, {0x54596ee3, {0x40000c84b0, 0x28}, {{0x4001186040, ...}, ...}}})
        /home/pi/go-librespot/cmd/daemon/player.go:359 +0x98 fp=0x4000f513d0 sp=0x4000f51130 pc=0xc30258
main.(*AppPlayer).Run(0x400035d880, {0xf83ba8, 0x14e33a0}, 0x400058dea0, 0x400058df10)
        /home/pi/go-librespot/cmd/daemon/player.go:657 +0x7fc fp=0x4000f51f70 sp=0x4000f513d0 pc=0xc34c7c
main.(*App).withAppPlayer.func3.gowrap1()
        /home/pi/go-librespot/cmd/daemon/main.go:360 +0x5c fp=0x4000f51fd0 sp=0x4000f51f70 pc=0xc291ec
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000f51fd0 sp=0x4000f51fd0 pc=0x482c04
created by main.(*App).withAppPlayer.func3 in goroutine 1
        /home/pi/go-librespot/cmd/daemon/main.go:360 +0x640
goroutine 2579536 gp=0x400001ddc0 m=nil [runnable]:
crypto/internal/fips140/aes.newCTR(_, {_, _, _})
        /usr/lib/go-1.25/src/crypto/internal/fips140/aes/ctr.go:28 +0x18c fp=0x40002ed280 sp=0x40002ed280 pc=0xc4b2fc
crypto/internal/fips140/aes.NewCTR(0x40013c0a00, {0x4002eb5430, 0x10, 0x10})
        /usr/lib/go-1.25/src/crypto/internal/fips140/aes/ctr.go:25 +0x58 fp=0x40002ed4c0 sp=0x40002ed280 pc=0xc4b118
crypto/cipher.NewCTR({0xf83500, 0x40013c0a00}, {0x4002eb5430, 0x10, 0x10})
        /usr/lib/go-1.25/src/crypto/cipher/ctr.go:43 +0xac fp=0x40002ed5f0 sp=0x40002ed4c0 pc=0x61e20c
github.com/devgianlu/go-librespot/audio.(*Decryptor).ReadAt(0x4001934800, {0x7f30213f20, 0x937, 0x7ffff936}, 0xc9f770)
        /home/pi/go-librespot/audio/decryptor.go:41 +0x17c fp=0x40002ed710 sp=0x40002ed5f0 pc=0xa08edc
io.(*SectionReader).Read(0x40026f6150, {0x7f30213f20, 0x937, 0x7ffff936})
        /usr/lib/go-1.25/src/io/io.go:516 +0x11c fp=0x40002ed7a0 sp=0x40002ed710 pc=0x528f1c
io.ReadAtLeast({0xf7d060, 0x40026f6150}, {0x7f30213857, 0x1000, 0x7fffffff}, 0x1000)
        /usr/lib/go-1.25/src/io/io.go:335 +0x138 fp=0x40002ed840 sp=0x40002ed7a0 pc=0x527f78
io.ReadFull({0xf7d060, 0x40026f6150}, {0x7f30213857, 0x1000, 0x7fffffff})
        /usr/lib/go-1.25/src/io/io.go:354 +0x68 fp=0x40002ed8d0 sp=0x40002ed840 pc=0x528118
github.com/devgianlu/go-librespot/vorbis.(*Decoder).readChunk(0x40002b0c08)
        /home/pi/go-librespot/vorbis/decoder.go:172 +0xd8 fp=0x40002ed9c0 sp=0x40002ed8d0 pc=0xaae3a8
github.com/devgianlu/go-librespot/vorbis.(*Decoder).readNextPage(0x40002b0c08)
        /home/pi/go-librespot/vorbis/decoder.go:308 +0xb8 fp=0x40002edb10 sp=0x40002ed9c0 pc=0xaaf138
github.com/devgianlu/go-librespot/vorbis.(*Decoder).Read(0x40002b0c08, {0x4000880000, 0x2738, 0x2738})
        /home/pi/go-librespot/vorbis/decoder.go:270 +0x2f0 fp=0x40002edc50 sp=0x40002edb10 pc=0xaaeda0
github.com/devgianlu/go-librespot/player.(*SwitchingAudioSource).Read(0x40002deb20, {0x4000880000, 0x2738, 0x2738})
        /home/pi/go-librespot/player/source.go:53 +0x19c fp=0x40002edd90 sp=0x40002edc50 pc=0xab826c
github.com/devgianlu/go-librespot/output.(*alsaOutput).outputLoop(0x4000128380, 0x7f100c7340)
        /home/pi/go-librespot/output/driver-alsa.go:393 +0x1c8 fp=0x40002edfa0 sp=0x40002edd90 pc=0xa233b8
github.com/devgianlu/go-librespot/output.(*alsaOutput).setupPcm.gowrap1()
        /home/pi/go-librespot/output/driver-alsa.go:233 +0x34 fp=0x40002edfd0 sp=0x40002edfa0 pc=0xa20e24
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40002edfd0 sp=0x40002edfd0 pc=0x482c04
created by github.com/devgianlu/go-librespot/output.(*alsaOutput).setupPcm in goroutine 2579421
        /home/pi/go-librespot/output/driver-alsa.go:233 +0x9fc
goroutine 2579447 gp=0x40008461c0 m=nil [select]:
runtime.gopark(0xf2a768, 0x0, 0x9, 0x3, 0x1)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40002f1d40 sp=0x40002f1d10 pc=0x47b854
runtime.selectgo(0x40002f1f18, 0x40002f1ee0, 0x3c?, 0x0, 0x1?, 0x1)
        /usr/lib/go-1.25/src/runtime/select.go:351 +0x814 fp=0x40002f1ea0 sp=0x40002f1d40 pc=0x45c2d4
github.com/devgianlu/go-librespot/ap.(*Accesspoint).pongAckTicker(0x40001451d0)
        /home/pi/go-librespot/ap/ap.go:355 +0xa4 fp=0x40002f1fb0 sp=0x40002f1ea0 pc=0x9fe734
github.com/devgianlu/go-librespot/ap.(*Accesspoint).startReceiving.func1.gowrap2()
        /home/pi/go-librespot/ap/ap.go:264 +0x2c fp=0x40002f1fd0 sp=0x40002f1fb0 pc=0x9fdc7c
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40002f1fd0 sp=0x40002f1fd0 pc=0x482c04
created by github.com/devgianlu/go-librespot/ap.(*Accesspoint).startReceiving.func1 in goroutine 2579422
        /home/pi/go-librespot/ap/ap.go:264 +0x174
goroutine 3810717 gp=0x400037dc00 m=nil [chan send, 21 minutes]:
runtime.gopark(0xf2a3e8, 0x40004514f8, 0xf, 0x6, 0x2)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000682b90 sp=0x4000682b60 pc=0x47b854
runtime.chansend(0x4000451490, 0x4000682ee8, 0x1, 0x4000145270?)
        /usr/lib/go-1.25/src/runtime/chan.go:283 +0x1fc fp=0x4000682c00 sp=0x4000682b90 pc=0x41733c
runtime.chansend1(0x4000145260?, 0x400034dbc0?)
        /usr/lib/go-1.25/src/runtime/chan.go:161 +0x18 fp=0x4000682c30 sp=0x4000682c00 pc=0x417128
github.com/devgianlu/go-librespot/ap.(*Accesspoint).recvLoop(0x40001451d0)
        /home/pi/go-librespot/ap/ap.go:305 +0x680 fp=0x4000682fb0 sp=0x4000682c30 pc=0x9fe390
github.com/devgianlu/go-librespot/ap.(*Accesspoint).reconnect.gowrap1()
        /home/pi/go-librespot/ap/ap.go:390 +0x2c fp=0x4000682fd0 sp=0x4000682fb0 pc=0x9febbc
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000682fd0 sp=0x4000682fd0 pc=0x482c04
created by github.com/devgianlu/go-librespot/ap.(*Accesspoint).reconnect in goroutine 3810711
        /home/pi/go-librespot/ap/ap.go:390 +0x214
goroutine 2579475 gp=0x40003eb340 m=nil [select, 38 minutes]:
runtime.gopark(0xf2a768, 0x0, 0x9, 0x3, 0x1)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000f3f6f0 sp=0x4000f3f6c0 pc=0x47b854
runtime.selectgo(0x4000f3fb48, 0x4000cc38a4, 0x10?, 0x0, 0xd33ca0?, 0x1)
        /usr/lib/go-1.25/src/runtime/select.go:351 +0x814 fp=0x4000f3f850 sp=0x4000f3f6f0 pc=0x45c2d4
github.com/devgianlu/go-librespot/audio.(*KeyProvider).recvLoop(0x400039f800)
        /home/pi/go-librespot/audio/provider.go:63 +0x1bc fp=0x4000f3ffb0 sp=0x4000f3f850 pc=0xa099bc
github.com/devgianlu/go-librespot/audio.(*KeyProvider).startReceiving.func1.gowrap1()
        /home/pi/go-librespot/audio/provider.go:53 +0x2c fp=0x4000f3ffd0 sp=0x4000f3ffb0 pc=0xa097cc
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000f3ffd0 sp=0x4000f3ffd0 pc=0x482c04
created by github.com/devgianlu/go-librespot/audio.(*KeyProvider).startReceiving.func1 in goroutine 2579422
        /home/pi/go-librespot/audio/provider.go:53 +0x78
goroutine 2579543 gp=0x40003c5340 m=3 mp=0x4000061008 [syscall, 104 minutes]:
runtime.cgocall(0xce42e0, 0x4000a89e98)
        /usr/lib/go-1.25/src/runtime/cgocall.go:167 +0x44 fp=0x4000a89e40 sp=0x4000a89e00 pc=0x478c14
github.com/devgianlu/go-librespot/output._Cfunc_snd_mixer_wait(0x7f080949d0, 0xffffffff)
        _cgo_gotypes.go:415 +0x30 fp=0x4000a89e90 sp=0x4000a89e40 pc=0xa1e4d0
github.com/devgianlu/go-librespot/output.(*alsaOutput).waitForMixerEvents.func1(0x4000128380)
        /home/pi/go-librespot/output/mixer-alsa.go:81 +0x64 fp=0x4000a89ee0 sp=0x4000a89e90 pc=0xa26664
github.com/devgianlu/go-librespot/output.(*alsaOutput).waitForMixerEvents(0x4000128380)
        /home/pi/go-librespot/output/mixer-alsa.go:81 +0x40 fp=0x4000a89fb0 sp=0x4000a89ee0 pc=0xa26110
github.com/devgianlu/go-librespot/output.(*alsaOutput).setupMixer.gowrap1()
        /home/pi/go-librespot/output/mixer-alsa.go:70 +0x2c fp=0x4000a89fd0 sp=0x4000a89fb0 pc=0xa2571c
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000a89fd0 sp=0x4000a89fd0 pc=0x482c04
created by github.com/devgianlu/go-librespot/output.(*alsaOutput).setupMixer in goroutine 2579421
        /home/pi/go-librespot/output/mixer-alsa.go:70 +0x590
goroutine 2579421 gp=0x400046ac40 m=nil [sync.Mutex.Lock, 32 minutes]:
runtime.gopark(0xf2a700, 0x14c6080, 0x16, 0x5, 0x6)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40036a99c0 sp=0x40036a9990 pc=0x47b854
runtime.goparkunlock(0x14c6080?, 0x4c?, 0xe3?, 0x4002cff260?)
        /usr/lib/go-1.25/src/runtime/proc.go:466 +0x34 fp=0x40036a99f0 sp=0x40036a99c0 pc=0x44b194
runtime.semacquire1(0x40000cd2f4, 0x0, 0x3, 0x2, 0x16)
        /usr/lib/go-1.25/src/runtime/sema.go:192 +0x148 fp=0x40036a9a40 sp=0x40036a99f0 pc=0x45cd58
internal/sync.runtime_SemacquireMutex(0x400004c608?, 0x8?, 0x40036a9aa8?)
        /usr/lib/go-1.25/src/runtime/sema.go:95 +0x28 fp=0x40036a9a80 sp=0x40036a9a40 pc=0x47ce88
internal/sync.(*Mutex).lockSlow(0x40000cd2f0)
        /usr/lib/go-1.25/src/internal/sync/mutex.go:149 +0x330 fp=0x40036a9b00 sp=0x40036a9a80 pc=0x490f40
internal/sync.(*Mutex).Lock(0x40000cd2f0)
        /usr/lib/go-1.25/src/internal/sync/mutex.go:70 +0x8c fp=0x40036a9b30 sp=0x40036a9b00 pc=0x490b1c
sync.(*Mutex).Lock(0x40000cd2f0)
        /usr/lib/go-1.25/src/sync/mutex.go:46 +0x28 fp=0x40036a9b50 sp=0x40036a9b30 pc=0x491cc8
github.com/devgianlu/go-librespot/player.(*SwitchingAudioSource).PositionMs(0x40002deb20)
        /home/pi/go-librespot/player/source.go:88 +0x44 fp=0x40036a9c10 sp=0x40036a9b50 pc=0xab86f4
github.com/devgianlu/go-librespot/player.(*Player).manageLoop(0x40004c7500)
        /home/pi/go-librespot/player/player.go:297 +0x9e0 fp=0x40036a9fb0 sp=0x40036a9c10 pc=0xab49d0
github.com/devgianlu/go-librespot/player.NewPlayer.gowrap1()
        /home/pi/go-librespot/player/player.go:183 +0x2c fp=0x40036a9fd0 sp=0x40036a9fb0 pc=0xab3bec
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40036a9fd0 sp=0x40036a9fd0 pc=0x482c04
created by github.com/devgianlu/go-librespot/player.NewPlayer in goroutine 1
        /home/pi/go-librespot/player/player.go:183 +0x3d8
goroutine 2579449 gp=0x400137c540 m=nil [select, 11 minutes]:
runtime.gopark(0xf2a768, 0x0, 0x9, 0x3, 0x1)
        /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000713c70 sp=0x4000713c40 pc=0x47b854
runtime.selectgo(0x4000713f40, 0x4000315e20, 0x0?, 0x0, 0x1?, 0x1)
        /usr/lib/go-1.25/src/runtime/select.go:351 +0x814 fp=0x4000713dd0 sp=0x4000713c70 pc=0x45c2d4
github.com/devgianlu/go-librespot/dealer.(*Dealer).pingTicker(0x40001be540)
        /home/pi/go-librespot/dealer/dealer.go:138 +0xa4 fp=0x4000713fb0 sp=0x4000713dd0 pc=0xadeeb4
github.com/devgianlu/go-librespot/dealer.(*Dealer).startReceiving.func1.gowrap2()
        /home/pi/go-librespot/dealer/dealer.go:129 +0x2c fp=0x4000713fd0 sp=0x4000713fb0 pc=0xaded7c
runtime.goexit({})
        /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000713fd0 sp=0x4000713fd0 pc=0x482c04
created by github.com/devgianlu/go-librespot/dealer.(*Dealer).startReceiving.func1 in goroutine 2579422
        /home/pi/go-librespot/dealer/dealer.go:129 +0x174
r0      0xfffffffffffffffc
r1      0x0
r2      0x0
r3      0x0
r4      0x3e8
r5      0x4e20
r6      0x989680
r7      0x13922a
r8      0x65
r9      0x1dbe0f510b8ea4
r10     0xffffffffffffff
r11     0x13c2c239810
r12     0x7f28f9f180
r13     0x7f3a6bc610
r14     0x7772207366706d74
r15     0x0
r16     0x7f39ebd010
r17     0x7f3a6bbf70
r18     0x9f000
r19     0x480650
r20     0x7f3a6bc740
r21     0x4000060808
r22     0x1
r23     0x80ea40
r24     0x7ff703a027
r25     0x4000052b58
r26     0xf2a6a8
r27     0xffffffffffffff80
r28     0x4000002a80
r29     0x7f3a6bc758
lr      0x455750
sp      0x7f3a6bc760
pc      0x4839f8
fault   0x0
Originally created by @tooxo on GitHub (Sep 16, 2025). Original GitHub issue: https://github.com/devgianlu/go-librespot/issues/211 Reading the documentation for the `ReaderAt` interface, it states: ```go // When ReadAt returns n < len(p), it returns a non-nil error // explaining why more bytes were not returned. In this respect, // ReadAt is stricter than Read. ``` Looking at the implementation of ReadAt in the HttpChunkedReader: https://github.com/devgianlu/go-librespot/blob/8d888e4e46e3966c9c1750bcaec3478f24e521b3/audio/chunked_reader.go#L223-L225 This case can (and does according to my debugger) return the tuple (0, nil), which is an illegal result value according to the documentation. I observed this, because this call https://github.com/devgianlu/go-librespot/blob/8d888e4e46e3966c9c1750bcaec3478f24e521b3/vorbis/decoder.go#L172 never returned, blocking the entire program as well as the dealer loop. I'm not entirely sure what the correct return value would be here, i would assume (n, io.EOF), but I would like some advice on this. <details> <summary>Core Dump</summary> ``` SIGTRAP: trace trap PC=0x4839f8 m=2 sigcode=0 goroutine 0 gp=0x4000002a80 m=2 mp=0x4000060808 [idle]: runtime.usleep(0x14) /usr/lib/go-1.25/src/runtime/sys_linux_arm64.s:139 +0x48 fp=0x7f3a6bc790 sp=0x7f3a6bc760 pc=0x4839f8 runtime.sysmon() /usr/lib/go-1.25/src/runtime/proc.go:6234 +0xd0 fp=0x7f3a6bc830 sp=0x7f3a6bc790 pc=0x455750 runtime.mstart1() /usr/lib/go-1.25/src/runtime/proc.go:1928 +0xa8 fp=0x7f3a6bc860 sp=0x7f3a6bc830 pc=0x44dd98 runtime.mstart0() /usr/lib/go-1.25/src/runtime/proc.go:1881 +0x68 fp=0x7f3a6bc890 sp=0x7f3a6bc860 pc=0x44dcc8 runtime.mstart() /usr/lib/go-1.25/src/runtime/asm_arm64.s:179 +0x10 fp=0x7f3a6bc8a0 sp=0x7f3a6bc890 pc=0x480660 goroutine 1 gp=0x40000021c0 m=nil [select, 116 minutes]: runtime.gopark(0xf2a768, 0x0, 0x9, 0x3, 0x1) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400078b540 sp=0x400078b510 pc=0x47b854 runtime.selectgo(0x400078b7d8, 0x40006936f8, 0x400000c900?, 0x0, 0x100?, 0x1) /usr/lib/go-1.25/src/runtime/select.go:351 +0x814 fp=0x400078b6a0 sp=0x400078b540 pc=0x45c2d4 github.com/devgianlu/go-librespot/zeroconf.(*Zeroconf).Serve(0x400032c140, 0x400078ba30) /home/pi/go-librespot/zeroconf/zeroconf.go:283 +0x258 fp=0x400078b870 sp=0x400078b6a0 pc=0xb82198 main.(*App).withAppPlayer(0x40001fa300, {0xf83ba8, 0x14e33a0}, 0x400003c690) /home/pi/go-librespot/cmd/daemon/main.go:323 +0x958 fp=0x400078bb40 sp=0x400078b870 pc=0xc289a8 main.(*App).Zeroconf(0x40001fa300, {0xf83ba8, 0x14e33a0}) /home/pi/go-librespot/cmd/daemon/main.go:172 +0x8c fp=0x400078bba0 sp=0x400078bb40 pc=0xc2776c main.main() /home/pi/go-librespot/cmd/daemon/main.go:562 +0x820 fp=0x400078bf60 sp=0x400078bba0 pc=0xc2b460 runtime.main() /usr/lib/go-1.25/src/runtime/proc.go:285 +0x218 fp=0x400078bfd0 sp=0x400078bf60 pc=0x44ad18 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400078bfd0 sp=0x400078bfd0 pc=0x482c04 goroutine 18 gp=0x4000092380 m=nil [force gc (idle), 11 minutes]: runtime.gopark(0xf2a700, 0x14b9ac0, 0x11, 0xa, 0x1) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000056770 sp=0x4000056740 pc=0x47b854 runtime.goparkunlock(0x14b9ac0?, 0x0?, 0x0?, 0x0?) /usr/lib/go-1.25/src/runtime/proc.go:466 +0x34 fp=0x40000567a0 sp=0x4000056770 pc=0x44b194 runtime.forcegchelper() /usr/lib/go-1.25/src/runtime/proc.go:373 +0xb0 fp=0x40000567d0 sp=0x40000567a0 pc=0x44b060 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40000567d0 sp=0x40000567d0 pc=0x482c04 created by runtime.init.7 in goroutine 1 /usr/lib/go-1.25/src/runtime/proc.go:361 +0x24 goroutine 19 gp=0x4000092540 m=nil [runnable]: runtime.goschedIfBusy() /usr/lib/go-1.25/src/runtime/proc.go:412 +0x34 fp=0x4000056f70 sp=0x4000056f50 pc=0x44b144 runtime.bgsweep(0x40000a2000) /usr/lib/go-1.25/src/runtime/mgcsweep.go:308 +0x164 fp=0x4000056fb0 sp=0x4000056f70 pc=0x434c04 runtime.gcenable.gowrap1() /usr/lib/go-1.25/src/runtime/mgc.go:212 +0x28 fp=0x4000056fd0 sp=0x4000056fb0 pc=0x428e88 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000056fd0 sp=0x4000056fd0 pc=0x482c04 created by runtime.gcenable in goroutine 1 /usr/lib/go-1.25/src/runtime/mgc.go:212 +0x6c goroutine 20 gp=0x4000092700 m=nil [GC scavenge wait]: runtime.gopark(0xf2a700, 0x14bb900, 0xd, 0xa, 0x2) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000057720 sp=0x40000576f0 pc=0x47b854 runtime.goparkunlock(0x14bb900?, 0x0?, 0x0?, 0x0?) /usr/lib/go-1.25/src/runtime/proc.go:466 +0x34 fp=0x4000057750 sp=0x4000057720 pc=0x44b194 runtime.(*scavengerState).park(0x14bb900) /usr/lib/go-1.25/src/runtime/mgcscavenge.go:425 +0x4c fp=0x4000057780 sp=0x4000057750 pc=0x43232c runtime.bgscavenge(0x40000a2000) /usr/lib/go-1.25/src/runtime/mgcscavenge.go:658 +0x60 fp=0x40000577b0 sp=0x4000057780 pc=0x432870 runtime.gcenable.gowrap2() /usr/lib/go-1.25/src/runtime/mgc.go:213 +0x28 fp=0x40000577d0 sp=0x40000577b0 pc=0x428e28 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40000577d0 sp=0x40000577d0 pc=0x482c04 created by runtime.gcenable in goroutine 1 /usr/lib/go-1.25/src/runtime/mgc.go:213 +0xac goroutine 2 gp=0x4000003340 m=nil [finalizer wait, 38 minutes]: runtime.gopark(0xf2a440, 0x14e35d8, 0x10, 0xa, 0x1) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400051bd80 sp=0x400051bd50 pc=0x47b854 runtime.runFinalizers() /usr/lib/go-1.25/src/runtime/mfinal.go:210 +0xec fp=0x400051bfd0 sp=0x400051bd80 pc=0x427fbc runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400051bfd0 sp=0x400051bfd0 pc=0x482c04 created by runtime.createfing in goroutine 1 /usr/lib/go-1.25/src/runtime/mfinal.go:172 +0x4c goroutine 21 gp=0x4000093c00 m=nil [cleanup wait, 31 minutes]: runtime.gopark(0xf2a700, 0x14bbfe0, 0x2e, 0xa, 0x1) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400006df20 sp=0x400006def0 pc=0x47b854 runtime.goparkunlock(0x14bbfe8?, 0x4b?, 0x0?, 0x400006df88?) /usr/lib/go-1.25/src/runtime/proc.go:466 +0x34 fp=0x400006df50 sp=0x400006df20 pc=0x44b194 runtime.(*cleanupQueue).dequeue(0x14bbe60) /usr/lib/go-1.25/src/runtime/mcleanup.go:439 +0xa0 fp=0x400006df90 sp=0x400006df50 pc=0x424ea0 runtime.runCleanups() /usr/lib/go-1.25/src/runtime/mcleanup.go:635 +0x60 fp=0x400006dfd0 sp=0x400006df90 pc=0x425670 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400006dfd0 sp=0x400006dfd0 pc=0x482c04 created by runtime.(*cleanupQueue).createGs in goroutine 1 /usr/lib/go-1.25/src/runtime/mcleanup.go:589 +0xb0 goroutine 7 gp=0x400031a1c0 m=nil [GC worker (idle), 11 minutes]: runtime.gopark(0xf2a458, 0x4000308600, 0x1c, 0xa, 0x0) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40002e0f00 sp=0x40002e0ed0 pc=0x47b854 runtime.gcBgMarkWorker(0x4000181500) /usr/lib/go-1.25/src/runtime/mgc.go:1463 +0xdc fp=0x40002e0fb0 sp=0x40002e0f00 pc=0x42ab7c runtime.gcBgMarkStartWorkers.gowrap1() /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x28 fp=0x40002e0fd0 sp=0x40002e0fb0 pc=0x42aa48 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40002e0fd0 sp=0x40002e0fd0 pc=0x482c04 created by runtime.gcBgMarkStartWorkers in goroutine 23 /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x6c goroutine 8 gp=0x400031ae00 m=nil [GC worker (idle), 11 minutes]: runtime.gopark(0xf2a458, 0x4000308800, 0x1c, 0xa, 0x0) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000070f00 sp=0x4000070ed0 pc=0x47b854 runtime.gcBgMarkWorker(0x4000181500) /usr/lib/go-1.25/src/runtime/mgc.go:1463 +0xdc fp=0x4000070fb0 sp=0x4000070f00 pc=0x42ab7c runtime.gcBgMarkStartWorkers.gowrap1() /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x28 fp=0x4000070fd0 sp=0x4000070fb0 pc=0x42aa48 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000070fd0 sp=0x4000070fd0 pc=0x482c04 created by runtime.gcBgMarkStartWorkers in goroutine 23 /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x6c goroutine 9 gp=0x400031afc0 m=nil [GC worker (idle)]: runtime.gopark(0xf2a458, 0x4000308a00, 0x1c, 0xa, 0x0) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400051af00 sp=0x400051aed0 pc=0x47b854 runtime.gcBgMarkWorker(0x4000181500) /usr/lib/go-1.25/src/runtime/mgc.go:1463 +0xdc fp=0x400051afb0 sp=0x400051af00 pc=0x42ab7c runtime.gcBgMarkStartWorkers.gowrap1() /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x28 fp=0x400051afd0 sp=0x400051afb0 pc=0x42aa48 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400051afd0 sp=0x400051afd0 pc=0x482c04 created by runtime.gcBgMarkStartWorkers in goroutine 23 /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x6c goroutine 10 gp=0x400031b180 m=nil [GC worker (idle)]: runtime.gopark(0xf2a458, 0x4000308c00, 0x1c, 0xa, 0x0) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40002e3f00 sp=0x40002e3ed0 pc=0x47b854 runtime.gcBgMarkWorker(0x4000181500) /usr/lib/go-1.25/src/runtime/mgc.go:1463 +0xdc fp=0x40002e3fb0 sp=0x40002e3f00 pc=0x42ab7c runtime.gcBgMarkStartWorkers.gowrap1() /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x28 fp=0x40002e3fd0 sp=0x40002e3fb0 pc=0x42aa48 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40002e3fd0 sp=0x40002e3fd0 pc=0x482c04 created by runtime.gcBgMarkStartWorkers in goroutine 23 /usr/lib/go-1.25/src/runtime/mgc.go:1373 +0x6c goroutine 37 gp=0x4000392540 m=nil [chan receive, 518 minutes]: runtime.gopark(0xf2a3e8, 0x40004f8148, 0xe, 0x7, 0x2) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400005de70 sp=0x400005de40 pc=0x47b854 runtime.chanrecv(0x40004f80e0, 0x400005df88, 0x1) /usr/lib/go-1.25/src/runtime/chan.go:667 +0x2c8 fp=0x400005def0 sp=0x400005de70 pc=0x417e78 runtime.chanrecv2(0x400003c680?, 0x0?) /usr/lib/go-1.25/src/runtime/chan.go:514 +0x14 fp=0x400005df20 sp=0x400005def0 pc=0x417b94 main.(*App).withAppPlayer.func1() /home/pi/go-librespot/cmd/daemon/main.go:270 +0x74 fp=0x400005dfd0 sp=0x400005df20 pc=0xc29774 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400005dfd0 sp=0x400005dfd0 pc=0x482c04 created by main.(*App).withAppPlayer in goroutine 1 /home/pi/go-librespot/cmd/daemon/main.go:267 +0x760 goroutine 38 gp=0x4000392700 m=nil [chan receive, 285 minutes]: runtime.gopark(0xf2a3e8, 0x40001800d8, 0xe, 0x7, 0x2) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40005a4dc0 sp=0x40005a4d90 pc=0x47b854 runtime.chanrecv(0x4000180070, 0x4000edffa8, 0x1) /usr/lib/go-1.25/src/runtime/chan.go:667 +0x2c8 fp=0x40005a4e40 sp=0x40005a4dc0 pc=0x417e78 runtime.chanrecv2(0x400032c140?, 0x0?) /usr/lib/go-1.25/src/runtime/chan.go:514 +0x14 fp=0x40005a4e70 sp=0x40005a4e40 pc=0x417b94 main.(*App).withAppPlayer.func2() /home/pi/go-librespot/cmd/daemon/main.go:286 +0x80 fp=0x40005a4fd0 sp=0x40005a4e70 pc=0xc292a0 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40005a4fd0 sp=0x40005a4fd0 pc=0x482c04 created by main.(*App).withAppPlayer in goroutine 1 /home/pi/go-librespot/cmd/daemon/main.go:283 +0x8d4 goroutine 11 gp=0x40002ae8c0 m=nil [IO wait]: runtime.gopark(0xf2a6e0, 0x7f39e74620, 0x2, 0x2, 0x5) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40003177d0 sp=0x40003177a0 pc=0x47b854 runtime.netpollblock(0x7f39e74600, 0x72, 0x0) /usr/lib/go-1.25/src/runtime/netpoll.go:575 +0xb8 fp=0x4000317810 sp=0x40003177d0 pc=0x443b58 internal/poll.runtime_pollWait(0x7f39e74600, 0x72) /usr/lib/go-1.25/src/runtime/netpoll.go:351 +0x48 fp=0x4000317830 sp=0x4000317810 pc=0x47ad18 internal/poll.(*pollDesc).wait(0x40000fa6a0, 0x72, 0x0) /usr/lib/go-1.25/src/internal/poll/fd_poll_runtime.go:84 +0x84 fp=0x4000317880 sp=0x4000317830 pc=0x535e14 internal/poll.(*pollDesc).waitRead(0x40000fa6a0, 0x0) /usr/lib/go-1.25/src/internal/poll/fd_poll_runtime.go:89 +0x38 fp=0x40003178d0 sp=0x4000317880 pc=0x535e98 internal/poll.(*FD).RawRead(0x40000fa680, 0x40008a4b90) /usr/lib/go-1.25/src/internal/poll/fd_unix.go:710 +0x180 fp=0x40003179a0 sp=0x40003178d0 pc=0x53c470 net.(*rawConn).Read(0x400005e0a8, 0x40008a4b90) /usr/lib/go-1.25/src/net/rawconn.go:44 +0x58 fp=0x4000317a20 sp=0x40003179a0 pc=0x5f7618 golang.org/x/net/internal/socket.(*Conn).recvMsg(0x40000a01a0, 0x400033be00, 0x0) /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/internal/socket/rawconn_msg.go:27 +0x2b8 fp=0x4000317ac0 sp=0x4000317a20 pc=0xafc938 golang.org/x/net/internal/socket.(*Conn).RecvMsg(0x40000a01a0, 0x400033be00, 0x0) /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/internal/socket/socket.go:247 +0x3c fp=0x4000317b10 sp=0x4000317ac0 pc=0xafdd9c golang.org/x/net/ipv4.(*payloadHandler).ReadFrom(0x4000342150, {0x4000420000, 0x10000, 0x10000}) /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/ipv4/payload_cmsg.go:31 +0x29c fp=0x4000317df0 sp=0x4000317b10 pc=0xb026ac github.com/grandcat/zeroconf.(*Server).recv4(0x400033a0c0, 0x4000342140) /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:254 +0x150 fp=0x4000317fa0 sp=0x4000317df0 pc=0xb7b3f0 github.com/grandcat/zeroconf.(*Server).mainloop.gowrap1() /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:188 +0x38 fp=0x4000317fd0 sp=0x4000317fa0 pc=0xb7afd8 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000317fd0 sp=0x4000317fd0 pc=0x482c04 created by github.com/grandcat/zeroconf.(*Server).mainloop in goroutine 35 /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:188 +0xcc goroutine 12 gp=0x40002aea80 m=nil [runnable]: runtime.(*_panic).start(0x40002ef920, 0x53c438, 0x40002ef990) /usr/lib/go-1.25/src/runtime/panic.go:809 +0x1b4 fp=0x40002ef900 sp=0x40002ef900 pc=0x4476e4 runtime.deferreturn() /usr/lib/go-1.25/src/runtime/panic.go:583 +0x50 fp=0x40002ef990 sp=0x40002ef900 pc=0x4470e0 internal/poll.(*FD).RawRead(0x40000fa780, 0x40005fdc70) /usr/lib/go-1.25/src/internal/poll/fd_unix.go:714 +0x148 fp=0x40002efa60 sp=0x40002ef990 pc=0x53c438 net.(*rawConn).Read(0x400005e0d0, 0x40005fdc70) /usr/lib/go-1.25/src/net/rawconn.go:44 +0x58 fp=0x40002efae0 sp=0x40002efa60 pc=0x5f7618 golang.org/x/net/internal/socket.(*Conn).recvMsg(0x40000a01c0, 0x40004f2ae0, 0x0) /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/internal/socket/rawconn_msg.go:27 +0x2b8 fp=0x40002efb80 sp=0x40002efae0 pc=0xafc938 golang.org/x/net/internal/socket.(*Conn).RecvMsg(0x40000a01c0, 0x40004f2ae0, 0x0) /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/internal/socket/socket.go:247 +0x3c fp=0x40002efbd0 sp=0x40002efb80 pc=0xafdd9c golang.org/x/net/ipv6.(*payloadHandler).ReadFrom(0x40003421a0, {0x4000410000, 0x10000, 0x10000}) /home/pi/go/pkg/mod/golang.org/x/net@v0.26.0/ipv6/payload_cmsg.go:31 +0x248 fp=0x40002efdf0 sp=0x40002efbd0 pc=0xb079b8 github.com/grandcat/zeroconf.(*Server).recv6(0x400033a0c0, 0x4000342190) /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:282 +0x150 fp=0x40002effa0 sp=0x40002efdf0 pc=0xb7b6e0 github.com/grandcat/zeroconf.(*Server).mainloop.gowrap2() /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:191 +0x38 fp=0x40002effd0 sp=0x40002effa0 pc=0xb7af68 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40002effd0 sp=0x40002effd0 pc=0x482c04 created by github.com/grandcat/zeroconf.(*Server).mainloop in goroutine 35 /home/pi/go/pkg/mod/github.com/grandcat/zeroconf@v1.0.0/server.go:191 +0x18c goroutine 39 gp=0x40003928c0 m=nil [IO wait, 13 minutes]: runtime.gopark(0xf2a6e0, 0x7f39e74820, 0x2, 0x2, 0x5) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40003134e0 sp=0x40003134b0 pc=0x47b854 runtime.netpollblock(0x7f39e74800, 0x72, 0x0) /usr/lib/go-1.25/src/runtime/netpoll.go:575 +0xb8 fp=0x4000313520 sp=0x40003134e0 pc=0x443b58 internal/poll.runtime_pollWait(0x7f39e74800, 0x72) /usr/lib/go-1.25/src/runtime/netpoll.go:351 +0x48 fp=0x4000313540 sp=0x4000313520 pc=0x47ad18 internal/poll.(*pollDesc).wait(0x40000fa320, 0x72, 0x0) /usr/lib/go-1.25/src/internal/poll/fd_poll_runtime.go:84 +0x84 fp=0x4000313590 sp=0x4000313540 pc=0x535e14 internal/poll.(*pollDesc).waitRead(0x40000fa320, 0x0) /usr/lib/go-1.25/src/internal/poll/fd_poll_runtime.go:89 +0x38 fp=0x40003135e0 sp=0x4000313590 pc=0x535e98 internal/poll.(*FD).Accept(0x40000fa300) /usr/lib/go-1.25/src/internal/poll/fd_unix.go:613 +0x364 fp=0x4000313850 sp=0x40003135e0 pc=0x53b5e4 net.(*netFD).accept(0x40000fa300) /usr/lib/go-1.25/src/net/fd_unix.go:161 +0x58 fp=0x40003139f0 sp=0x4000313850 pc=0x5dab18 net.(*TCPListener).accept(0x4000468300) /usr/lib/go-1.25/src/net/tcpsock_posix.go:159 +0x4c fp=0x4000313ae0 sp=0x40003139f0 pc=0x5fef3c net.(*TCPListener).Accept(0x4000468300) /usr/lib/go-1.25/src/net/tcpsock.go:380 +0x58 fp=0x4000313b90 sp=0x4000313ae0 pc=0x5fd268 net/http.(*onceCloseListener).Accept(0x400032a750) <autogenerated>:1 +0x60 fp=0x4000313c10 sp=0x4000313b90 pc=0x821c00 net/http.(*Server).Serve(0x40001fa600, {0xf82a90, 0x4000468300}) /usr/lib/go-1.25/src/net/http/server.go:3463 +0x3a4 fp=0x4000313ef0 sp=0x4000313c10 pc=0x7eb8b4 net/http.Serve({0xf82a90, 0x4000468300}, {0xf79fe8, 0x400019a000}) /usr/lib/go-1.25/src/net/http/server.go:2971 +0xe0 fp=0x4000313f50 sp=0x4000313ef0 pc=0x7ea580 github.com/devgianlu/go-librespot/zeroconf.(*Zeroconf).Serve.func2() /home/pi/go-librespot/zeroconf/zeroconf.go:280 +0x58 fp=0x4000313fd0 sp=0x4000313f50 pc=0xb822b8 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000313fd0 sp=0x4000313fd0 pc=0x482c04 created by github.com/devgianlu/go-librespot/zeroconf.(*Zeroconf).Serve in goroutine 1 /home/pi/go-librespot/zeroconf/zeroconf.go:280 +0x1b8 goroutine 2579448 gp=0x4000949180 m=nil [chan receive, 32 minutes]: runtime.gopark(0xf2a3e8, 0x400039c0d8, 0xe, 0x7, 0x2) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x400078f740 sp=0x400078f710 pc=0x47b854 runtime.chanrecv(0x400039c070, 0x4000041837, 0x1) /usr/lib/go-1.25/src/runtime/chan.go:667 +0x2c8 fp=0x400078f7c0 sp=0x400078f740 pc=0x417e78 runtime.chanrecv1(0x4000201180?, 0x0?) /usr/lib/go-1.25/src/runtime/chan.go:509 +0x14 fp=0x400078f7f0 sp=0x400078f7c0 pc=0x417b74 github.com/devgianlu/go-librespot/dealer.(*Dealer).handleRequest(0x40001be540, 0x400026a000) /home/pi/go-librespot/dealer/recv.go:237 +0x3fc fp=0x400078fc60 sp=0x400078f7f0 pc=0xae1b6c github.com/devgianlu/go-librespot/dealer.(*Dealer).recvLoop(0x40001be540) /home/pi/go-librespot/dealer/dealer.go:213 +0x9f0 fp=0x400078ffb0 sp=0x400078fc60 pc=0xadfc40 github.com/devgianlu/go-librespot/dealer.(*Dealer).startReceiving.func1.gowrap1() /home/pi/go-librespot/dealer/dealer.go:125 +0x2c fp=0x400078ffd0 sp=0x400078ffb0 pc=0xadeddc runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x400078ffd0 sp=0x400078ffd0 pc=0x482c04 created by github.com/devgianlu/go-librespot/dealer.(*Dealer).startReceiving.func1 in goroutine 2579422 /home/pi/go-librespot/dealer/dealer.go:125 +0xb0 goroutine 2579422 gp=0x400057fa40 m=nil [chan receive, 32 minutes]: runtime.gopark(0xf2a3e8, 0x40001a84c8, 0xe, 0x7, 0x2) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000f50770 sp=0x4000f50740 pc=0x47b854 runtime.chanrecv(0x40001a8460, 0x4000f50878, 0x1) /usr/lib/go-1.25/src/runtime/chan.go:667 +0x2c8 fp=0x4000f507f0 sp=0x4000f50770 pc=0x417e78 runtime.chanrecv1(0xac8a1c?, 0x1?) /usr/lib/go-1.25/src/runtime/chan.go:509 +0x14 fp=0x4000f50820 sp=0x4000f507f0 pc=0x417b74 github.com/devgianlu/go-librespot/player.(*Player).PositionMs(0x40004c7500) /home/pi/go-librespot/player/player.go:408 +0x84 fp=0x4000f508b0 sp=0x4000f50820 pc=0xab5324 main.(*AppPlayer).skipNext(0x400035d880, {0xf83ba8, 0x14e33a0}, 0x0) /home/pi/go-librespot/cmd/daemon/controls.go:565 +0x68 fp=0x4000f50ab0 sp=0x4000f508b0 pc=0xc24018 main.(*AppPlayer).handlePlayerCommand(_, {_, _}, {0x54596ee3, {0x40000c84b0, 0x28}, {{0x4001186040, 0x9}, {0x0, 0x0}, ...}}) /home/pi/go-librespot/cmd/daemon/player.go:313 +0x1c20 fp=0x4000f51130 sp=0x4000f50ab0 pc=0xc2e5a0 main.(*AppPlayer).handleDealerRequest(_, {_, _}, {0x400039c070, {0x40000c83f0, 0x24}, {0x54596ee3, {0x40000c84b0, 0x28}, {{0x4001186040, ...}, ...}}}) /home/pi/go-librespot/cmd/daemon/player.go:359 +0x98 fp=0x4000f513d0 sp=0x4000f51130 pc=0xc30258 main.(*AppPlayer).Run(0x400035d880, {0xf83ba8, 0x14e33a0}, 0x400058dea0, 0x400058df10) /home/pi/go-librespot/cmd/daemon/player.go:657 +0x7fc fp=0x4000f51f70 sp=0x4000f513d0 pc=0xc34c7c main.(*App).withAppPlayer.func3.gowrap1() /home/pi/go-librespot/cmd/daemon/main.go:360 +0x5c fp=0x4000f51fd0 sp=0x4000f51f70 pc=0xc291ec runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000f51fd0 sp=0x4000f51fd0 pc=0x482c04 created by main.(*App).withAppPlayer.func3 in goroutine 1 /home/pi/go-librespot/cmd/daemon/main.go:360 +0x640 goroutine 2579536 gp=0x400001ddc0 m=nil [runnable]: crypto/internal/fips140/aes.newCTR(_, {_, _, _}) /usr/lib/go-1.25/src/crypto/internal/fips140/aes/ctr.go:28 +0x18c fp=0x40002ed280 sp=0x40002ed280 pc=0xc4b2fc crypto/internal/fips140/aes.NewCTR(0x40013c0a00, {0x4002eb5430, 0x10, 0x10}) /usr/lib/go-1.25/src/crypto/internal/fips140/aes/ctr.go:25 +0x58 fp=0x40002ed4c0 sp=0x40002ed280 pc=0xc4b118 crypto/cipher.NewCTR({0xf83500, 0x40013c0a00}, {0x4002eb5430, 0x10, 0x10}) /usr/lib/go-1.25/src/crypto/cipher/ctr.go:43 +0xac fp=0x40002ed5f0 sp=0x40002ed4c0 pc=0x61e20c github.com/devgianlu/go-librespot/audio.(*Decryptor).ReadAt(0x4001934800, {0x7f30213f20, 0x937, 0x7ffff936}, 0xc9f770) /home/pi/go-librespot/audio/decryptor.go:41 +0x17c fp=0x40002ed710 sp=0x40002ed5f0 pc=0xa08edc io.(*SectionReader).Read(0x40026f6150, {0x7f30213f20, 0x937, 0x7ffff936}) /usr/lib/go-1.25/src/io/io.go:516 +0x11c fp=0x40002ed7a0 sp=0x40002ed710 pc=0x528f1c io.ReadAtLeast({0xf7d060, 0x40026f6150}, {0x7f30213857, 0x1000, 0x7fffffff}, 0x1000) /usr/lib/go-1.25/src/io/io.go:335 +0x138 fp=0x40002ed840 sp=0x40002ed7a0 pc=0x527f78 io.ReadFull({0xf7d060, 0x40026f6150}, {0x7f30213857, 0x1000, 0x7fffffff}) /usr/lib/go-1.25/src/io/io.go:354 +0x68 fp=0x40002ed8d0 sp=0x40002ed840 pc=0x528118 github.com/devgianlu/go-librespot/vorbis.(*Decoder).readChunk(0x40002b0c08) /home/pi/go-librespot/vorbis/decoder.go:172 +0xd8 fp=0x40002ed9c0 sp=0x40002ed8d0 pc=0xaae3a8 github.com/devgianlu/go-librespot/vorbis.(*Decoder).readNextPage(0x40002b0c08) /home/pi/go-librespot/vorbis/decoder.go:308 +0xb8 fp=0x40002edb10 sp=0x40002ed9c0 pc=0xaaf138 github.com/devgianlu/go-librespot/vorbis.(*Decoder).Read(0x40002b0c08, {0x4000880000, 0x2738, 0x2738}) /home/pi/go-librespot/vorbis/decoder.go:270 +0x2f0 fp=0x40002edc50 sp=0x40002edb10 pc=0xaaeda0 github.com/devgianlu/go-librespot/player.(*SwitchingAudioSource).Read(0x40002deb20, {0x4000880000, 0x2738, 0x2738}) /home/pi/go-librespot/player/source.go:53 +0x19c fp=0x40002edd90 sp=0x40002edc50 pc=0xab826c github.com/devgianlu/go-librespot/output.(*alsaOutput).outputLoop(0x4000128380, 0x7f100c7340) /home/pi/go-librespot/output/driver-alsa.go:393 +0x1c8 fp=0x40002edfa0 sp=0x40002edd90 pc=0xa233b8 github.com/devgianlu/go-librespot/output.(*alsaOutput).setupPcm.gowrap1() /home/pi/go-librespot/output/driver-alsa.go:233 +0x34 fp=0x40002edfd0 sp=0x40002edfa0 pc=0xa20e24 runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40002edfd0 sp=0x40002edfd0 pc=0x482c04 created by github.com/devgianlu/go-librespot/output.(*alsaOutput).setupPcm in goroutine 2579421 /home/pi/go-librespot/output/driver-alsa.go:233 +0x9fc goroutine 2579447 gp=0x40008461c0 m=nil [select]: runtime.gopark(0xf2a768, 0x0, 0x9, 0x3, 0x1) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40002f1d40 sp=0x40002f1d10 pc=0x47b854 runtime.selectgo(0x40002f1f18, 0x40002f1ee0, 0x3c?, 0x0, 0x1?, 0x1) /usr/lib/go-1.25/src/runtime/select.go:351 +0x814 fp=0x40002f1ea0 sp=0x40002f1d40 pc=0x45c2d4 github.com/devgianlu/go-librespot/ap.(*Accesspoint).pongAckTicker(0x40001451d0) /home/pi/go-librespot/ap/ap.go:355 +0xa4 fp=0x40002f1fb0 sp=0x40002f1ea0 pc=0x9fe734 github.com/devgianlu/go-librespot/ap.(*Accesspoint).startReceiving.func1.gowrap2() /home/pi/go-librespot/ap/ap.go:264 +0x2c fp=0x40002f1fd0 sp=0x40002f1fb0 pc=0x9fdc7c runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40002f1fd0 sp=0x40002f1fd0 pc=0x482c04 created by github.com/devgianlu/go-librespot/ap.(*Accesspoint).startReceiving.func1 in goroutine 2579422 /home/pi/go-librespot/ap/ap.go:264 +0x174 goroutine 3810717 gp=0x400037dc00 m=nil [chan send, 21 minutes]: runtime.gopark(0xf2a3e8, 0x40004514f8, 0xf, 0x6, 0x2) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000682b90 sp=0x4000682b60 pc=0x47b854 runtime.chansend(0x4000451490, 0x4000682ee8, 0x1, 0x4000145270?) /usr/lib/go-1.25/src/runtime/chan.go:283 +0x1fc fp=0x4000682c00 sp=0x4000682b90 pc=0x41733c runtime.chansend1(0x4000145260?, 0x400034dbc0?) /usr/lib/go-1.25/src/runtime/chan.go:161 +0x18 fp=0x4000682c30 sp=0x4000682c00 pc=0x417128 github.com/devgianlu/go-librespot/ap.(*Accesspoint).recvLoop(0x40001451d0) /home/pi/go-librespot/ap/ap.go:305 +0x680 fp=0x4000682fb0 sp=0x4000682c30 pc=0x9fe390 github.com/devgianlu/go-librespot/ap.(*Accesspoint).reconnect.gowrap1() /home/pi/go-librespot/ap/ap.go:390 +0x2c fp=0x4000682fd0 sp=0x4000682fb0 pc=0x9febbc runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000682fd0 sp=0x4000682fd0 pc=0x482c04 created by github.com/devgianlu/go-librespot/ap.(*Accesspoint).reconnect in goroutine 3810711 /home/pi/go-librespot/ap/ap.go:390 +0x214 goroutine 2579475 gp=0x40003eb340 m=nil [select, 38 minutes]: runtime.gopark(0xf2a768, 0x0, 0x9, 0x3, 0x1) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000f3f6f0 sp=0x4000f3f6c0 pc=0x47b854 runtime.selectgo(0x4000f3fb48, 0x4000cc38a4, 0x10?, 0x0, 0xd33ca0?, 0x1) /usr/lib/go-1.25/src/runtime/select.go:351 +0x814 fp=0x4000f3f850 sp=0x4000f3f6f0 pc=0x45c2d4 github.com/devgianlu/go-librespot/audio.(*KeyProvider).recvLoop(0x400039f800) /home/pi/go-librespot/audio/provider.go:63 +0x1bc fp=0x4000f3ffb0 sp=0x4000f3f850 pc=0xa099bc github.com/devgianlu/go-librespot/audio.(*KeyProvider).startReceiving.func1.gowrap1() /home/pi/go-librespot/audio/provider.go:53 +0x2c fp=0x4000f3ffd0 sp=0x4000f3ffb0 pc=0xa097cc runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000f3ffd0 sp=0x4000f3ffd0 pc=0x482c04 created by github.com/devgianlu/go-librespot/audio.(*KeyProvider).startReceiving.func1 in goroutine 2579422 /home/pi/go-librespot/audio/provider.go:53 +0x78 goroutine 2579543 gp=0x40003c5340 m=3 mp=0x4000061008 [syscall, 104 minutes]: runtime.cgocall(0xce42e0, 0x4000a89e98) /usr/lib/go-1.25/src/runtime/cgocall.go:167 +0x44 fp=0x4000a89e40 sp=0x4000a89e00 pc=0x478c14 github.com/devgianlu/go-librespot/output._Cfunc_snd_mixer_wait(0x7f080949d0, 0xffffffff) _cgo_gotypes.go:415 +0x30 fp=0x4000a89e90 sp=0x4000a89e40 pc=0xa1e4d0 github.com/devgianlu/go-librespot/output.(*alsaOutput).waitForMixerEvents.func1(0x4000128380) /home/pi/go-librespot/output/mixer-alsa.go:81 +0x64 fp=0x4000a89ee0 sp=0x4000a89e90 pc=0xa26664 github.com/devgianlu/go-librespot/output.(*alsaOutput).waitForMixerEvents(0x4000128380) /home/pi/go-librespot/output/mixer-alsa.go:81 +0x40 fp=0x4000a89fb0 sp=0x4000a89ee0 pc=0xa26110 github.com/devgianlu/go-librespot/output.(*alsaOutput).setupMixer.gowrap1() /home/pi/go-librespot/output/mixer-alsa.go:70 +0x2c fp=0x4000a89fd0 sp=0x4000a89fb0 pc=0xa2571c runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000a89fd0 sp=0x4000a89fd0 pc=0x482c04 created by github.com/devgianlu/go-librespot/output.(*alsaOutput).setupMixer in goroutine 2579421 /home/pi/go-librespot/output/mixer-alsa.go:70 +0x590 goroutine 2579421 gp=0x400046ac40 m=nil [sync.Mutex.Lock, 32 minutes]: runtime.gopark(0xf2a700, 0x14c6080, 0x16, 0x5, 0x6) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x40036a99c0 sp=0x40036a9990 pc=0x47b854 runtime.goparkunlock(0x14c6080?, 0x4c?, 0xe3?, 0x4002cff260?) /usr/lib/go-1.25/src/runtime/proc.go:466 +0x34 fp=0x40036a99f0 sp=0x40036a99c0 pc=0x44b194 runtime.semacquire1(0x40000cd2f4, 0x0, 0x3, 0x2, 0x16) /usr/lib/go-1.25/src/runtime/sema.go:192 +0x148 fp=0x40036a9a40 sp=0x40036a99f0 pc=0x45cd58 internal/sync.runtime_SemacquireMutex(0x400004c608?, 0x8?, 0x40036a9aa8?) /usr/lib/go-1.25/src/runtime/sema.go:95 +0x28 fp=0x40036a9a80 sp=0x40036a9a40 pc=0x47ce88 internal/sync.(*Mutex).lockSlow(0x40000cd2f0) /usr/lib/go-1.25/src/internal/sync/mutex.go:149 +0x330 fp=0x40036a9b00 sp=0x40036a9a80 pc=0x490f40 internal/sync.(*Mutex).Lock(0x40000cd2f0) /usr/lib/go-1.25/src/internal/sync/mutex.go:70 +0x8c fp=0x40036a9b30 sp=0x40036a9b00 pc=0x490b1c sync.(*Mutex).Lock(0x40000cd2f0) /usr/lib/go-1.25/src/sync/mutex.go:46 +0x28 fp=0x40036a9b50 sp=0x40036a9b30 pc=0x491cc8 github.com/devgianlu/go-librespot/player.(*SwitchingAudioSource).PositionMs(0x40002deb20) /home/pi/go-librespot/player/source.go:88 +0x44 fp=0x40036a9c10 sp=0x40036a9b50 pc=0xab86f4 github.com/devgianlu/go-librespot/player.(*Player).manageLoop(0x40004c7500) /home/pi/go-librespot/player/player.go:297 +0x9e0 fp=0x40036a9fb0 sp=0x40036a9c10 pc=0xab49d0 github.com/devgianlu/go-librespot/player.NewPlayer.gowrap1() /home/pi/go-librespot/player/player.go:183 +0x2c fp=0x40036a9fd0 sp=0x40036a9fb0 pc=0xab3bec runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x40036a9fd0 sp=0x40036a9fd0 pc=0x482c04 created by github.com/devgianlu/go-librespot/player.NewPlayer in goroutine 1 /home/pi/go-librespot/player/player.go:183 +0x3d8 goroutine 2579449 gp=0x400137c540 m=nil [select, 11 minutes]: runtime.gopark(0xf2a768, 0x0, 0x9, 0x3, 0x1) /usr/lib/go-1.25/src/runtime/proc.go:460 +0xd4 fp=0x4000713c70 sp=0x4000713c40 pc=0x47b854 runtime.selectgo(0x4000713f40, 0x4000315e20, 0x0?, 0x0, 0x1?, 0x1) /usr/lib/go-1.25/src/runtime/select.go:351 +0x814 fp=0x4000713dd0 sp=0x4000713c70 pc=0x45c2d4 github.com/devgianlu/go-librespot/dealer.(*Dealer).pingTicker(0x40001be540) /home/pi/go-librespot/dealer/dealer.go:138 +0xa4 fp=0x4000713fb0 sp=0x4000713dd0 pc=0xadeeb4 github.com/devgianlu/go-librespot/dealer.(*Dealer).startReceiving.func1.gowrap2() /home/pi/go-librespot/dealer/dealer.go:129 +0x2c fp=0x4000713fd0 sp=0x4000713fb0 pc=0xaded7c runtime.goexit({}) /usr/lib/go-1.25/src/runtime/asm_arm64.s:1268 +0x4 fp=0x4000713fd0 sp=0x4000713fd0 pc=0x482c04 created by github.com/devgianlu/go-librespot/dealer.(*Dealer).startReceiving.func1 in goroutine 2579422 /home/pi/go-librespot/dealer/dealer.go:129 +0x174 r0 0xfffffffffffffffc r1 0x0 r2 0x0 r3 0x0 r4 0x3e8 r5 0x4e20 r6 0x989680 r7 0x13922a r8 0x65 r9 0x1dbe0f510b8ea4 r10 0xffffffffffffff r11 0x13c2c239810 r12 0x7f28f9f180 r13 0x7f3a6bc610 r14 0x7772207366706d74 r15 0x0 r16 0x7f39ebd010 r17 0x7f3a6bbf70 r18 0x9f000 r19 0x480650 r20 0x7f3a6bc740 r21 0x4000060808 r22 0x1 r23 0x80ea40 r24 0x7ff703a027 r25 0x4000052b58 r26 0xf2a6a8 r27 0xffffffffffffff80 r28 0x4000002a80 r29 0x7f3a6bc758 lr 0x455750 sp 0x7f3a6bc760 pc 0x4839f8 fault 0x0 ``` </details
kerem 2026-02-28 14:25:43 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@tooxo commented on GitHub (Sep 17, 2025):

Also tangentially related:
github.com/devgianlu/go-librespot@8d888e4e46/audio/chunked_reader.go (L140-L145)

This should be chunk.err == nil, because if the chunk load results in an error, the chunk.fetching loop busy-loops, never unlocking the lock (.Wait() un-locks the lock), deadlocking the goroutine trying to set chunk.fetching to false.

E.g.:

github.com/devgianlu/go-librespot@8d888e4e46/audio/chunked_reader.go (L160-L164)

I am also not sure why the condition (rather the nested loop) is there in the first place, the loop should not have the opportunity to busy-loop in any scenario, because of deadlock and performance issues.

Core Dump (This dump is quite big, interesting goroutines would be 536716, 536743 as the ones being stuck and 526121, 526124, 526127 as the ones busy looping [there are tons more, just look at it using goroutine-analyzer])
https://gist.github.com/tooxo/f85b564a5f83da75f8246ce7ff3849d8

<!-- gh-comment-id:3302224793 --> @tooxo commented on GitHub (Sep 17, 2025): Also tangentially related: https://github.com/devgianlu/go-librespot/blob/8d888e4e46e3966c9c1750bcaec3478f24e521b3/audio/chunked_reader.go#L140-L145 This should be `chunk.err == nil`, because if the chunk load results in an error, the chunk.fetching loop busy-loops, never unlocking the lock (`.Wait()` un-locks the lock), deadlocking the goroutine trying to set chunk.fetching to false. E.g.: https://github.com/devgianlu/go-librespot/blob/8d888e4e46e3966c9c1750bcaec3478f24e521b3/audio/chunked_reader.go#L160-L164 I am also not sure why the condition (rather the nested loop) is there in the first place, the loop should not have the opportunity to busy-loop in any scenario, because of deadlock and performance issues. Core Dump (This dump is quite big, interesting goroutines would be 536716, 536743 as the ones being stuck and 526121, 526124, 526127 as the ones busy looping [there are tons more, just look at it using goroutine-analyzer]) https://gist.github.com/tooxo/f85b564a5f83da75f8246ce7ff3849d8
Author
Owner

@devgianlu commented on GitHub (Sep 18, 2025):

I don't see where the busy looping is, the goroutines that you mentioned are waiting to obtain a lock and not burning instructions in a loop.


github.com/devgianlu/go-librespot@8d888e4e46/audio/chunked_reader.go (L140-L145)

The idea behind this loop is that if the chunk is already being fetched (chunk.fetching) we wait until chunk.data or chunk.err become non-nil indicating that something has changed in the state of the chunk. If it's ready, we return early with the data, else we try to fetch it again.


github.com/devgianlu/go-librespot@8d888e4e46/audio/chunked_reader.go (L160-L164)

By setting fetching to false and err to a non-nil value, we ensure that when Broadcast is called any loop like the one mentioned above will exit.


I haven't inspected your dump, but hopefully this provides some insight. It surely is strange that there's a goroutine waiting for 16 minutes to obtain a lock.

<!-- gh-comment-id:3308679316 --> @devgianlu commented on GitHub (Sep 18, 2025): I don't see where the busy looping is, the goroutines that you mentioned are waiting to obtain a lock and not burning instructions in a loop. --- https://github.com/devgianlu/go-librespot/blob/8d888e4e46e3966c9c1750bcaec3478f24e521b3/audio/chunked_reader.go#L140-L145 The idea behind this loop is that if the chunk is already being fetched (`chunk.fetching`) we wait until `chunk.data` or `chunk.err` become non-nil indicating that something has changed in the state of the chunk. If it's ready, we return early with the data, else we try to fetch it again. --- https://github.com/devgianlu/go-librespot/blob/8d888e4e46e3966c9c1750bcaec3478f24e521b3/audio/chunked_reader.go#L160-L164 By setting `fetching` to `false` and `err` to a non-nil value, we ensure that when `Broadcast` is called any loop like the one mentioned above will exit. --- I haven't inspected your dump, but hopefully this provides some insight. It surely is strange that there's a goroutine waiting for 16 minutes to obtain a lock.
Author
Owner

@tooxo commented on GitHub (Sep 18, 2025):

I don't see where the busy looping is, the goroutines that you mentioned are waiting to obtain a lock and not burning instructions in a loop.

I'm sorry if I didn't articulate this clear enough, but the top comment and the answer are two issues, which are only related in the sense that both of them lock up the dealer loop somehow. Otherwise they are unrelated, so there is no busy loop in the upper core dump, but only in the lower one.

go-librespot/audio/chunked_reader.go

Lines 140 to 145 in 8d888e4
// if the chunk is already being fetched, wait until it is done
for chunk.fetching {
for !(chunk.data != nil || chunk.err != nil) {
chunk.Wait()
}
}

The idea behind this loop is that if the chunk is already being fetched (chunk.fetching) we wait until chunk.data or chunk.err become non-nil indicating that something has changed in the state of the chunk. If it's ready, we return early with the data, else we try to fetch it again.

go-librespot/audio/chunked_reader.go

Lines 160 to 164 in 8d888e4
chunk.L.Lock()
chunk.err = err
chunk.fetching = false
chunk.Broadcast()
chunk.L.Unlock()

By setting fetching to false and err to a non-nil value, we ensure that when Broadcast is called any loop like the one mentioned above will exit.

I haven't inspected your dump, but hopefully this provides some insight. It surely is strange that there's a goroutine waiting for 16 minutes to obtain a lock.

I am not sure if one can even see a busy loop in a core dump, but from what i saw in the debugger there is a scenario where err != nil and fetching is true.

for chunk.fetching { // condition is true
	for !(chunk.data != nil || chunk.err != nil) { // condition is false
		chunk.Wait()
	}
}

// so this is just equal to:
for chunk.fetching {}

Removing the inner loop will fix the issue, because from the programs logic, fetching = true should imply data and err to be nil, and fetching = false will imply one of them to be not-nil, so waiting until fetching is false would be enough anyway. Nesting these for loops only allows the described deadlock to happen. I hope the issue is more clear now.

<!-- gh-comment-id:3309866477 --> @tooxo commented on GitHub (Sep 18, 2025): > I don't see where the busy looping is, the goroutines that you mentioned are waiting to obtain a lock and not burning instructions in a loop. I'm sorry if I didn't articulate this clear enough, but the top comment and the answer are two issues, which are only related in the sense that both of them lock up the dealer loop somehow. Otherwise they are unrelated, so there is no busy loop in the upper core dump, but only in the lower one. > > [go-librespot/audio/chunked_reader.go](https://github.com/devgianlu/go-librespot/blob/8d888e4e46e3966c9c1750bcaec3478f24e521b3/audio/chunked_reader.go#L140-L145) > > Lines 140 to 145 in [8d888e4](/devgianlu/go-librespot/commit/8d888e4e46e3966c9c1750bcaec3478f24e521b3) > // if the chunk is already being fetched, wait until it is done > for chunk.fetching { > for !(chunk.data != nil || chunk.err != nil) { > chunk.Wait() > } > } > > The idea behind this loop is that if the chunk is already being fetched (`chunk.fetching`) we wait until `chunk.data` or `chunk.err` become non-nil indicating that something has changed in the state of the chunk. If it's ready, we return early with the data, else we try to fetch it again. > > [go-librespot/audio/chunked_reader.go](https://github.com/devgianlu/go-librespot/blob/8d888e4e46e3966c9c1750bcaec3478f24e521b3/audio/chunked_reader.go#L160-L164) > > Lines 160 to 164 in [8d888e4](/devgianlu/go-librespot/commit/8d888e4e46e3966c9c1750bcaec3478f24e521b3) > chunk.L.Lock() > chunk.err = err > chunk.fetching = false > chunk.Broadcast() > chunk.L.Unlock() > > By setting `fetching` to `false` and `err` to a non-nil value, we ensure that when `Broadcast` is called any loop like the one mentioned above will exit. > > I haven't inspected your dump, but hopefully this provides some insight. It surely is strange that there's a goroutine waiting for 16 minutes to obtain a lock. I am not sure if one can even see a busy loop in a core dump, but from what i saw in the debugger there is a scenario where err != nil and fetching is true. ```go for chunk.fetching { // condition is true for !(chunk.data != nil || chunk.err != nil) { // condition is false chunk.Wait() } } // so this is just equal to: for chunk.fetching {} ``` Removing the inner loop will fix the issue, because from the programs logic, fetching = true should imply data and err to be nil, and fetching = false will imply one of them to be not-nil, so waiting until fetching is false would be enough anyway. Nesting these for loops only allows the described deadlock to happen. I hope the issue is more clear now.
Author
Owner

@devgianlu commented on GitHub (Sep 19, 2025):

I see what you mean now, but I think we should focus on fixing where err != nil and fetching is true happens, that's the real bug. The fact that the two nested loops cause a busy loop is the effect of the bug.

Perhaps we should clear chunk.err and chunk.data here?

<!-- gh-comment-id:3311615877 --> @devgianlu commented on GitHub (Sep 19, 2025): I see what you mean now, but I think we should focus on fixing where `err != nil and fetching is true` happens, that's the real bug. The fact that the two nested loops cause a busy loop is the effect of the bug. Perhaps we should clear `chunk.err` and `chunk.data` [here](https://github.com/devgianlu/go-librespot/blob/05c1cc8c7bc291b924e5a1537184f826e463ceb2/audio/chunked_reader.go#L153)?
Author
Owner

@tooxo commented on GitHub (Sep 19, 2025):

I see what you mean now, but I think we should focus on fixing where err != nil and fetching is true happens, that's the real bug. The fact that the two nested loops cause a busy loop is the effect of the bug.

Perhaps we should clear chunk.err and chunk.data here?

Yes this would also be a solution. Clearing chunk.err would be enough, because otherwise the function would have returned at this point anyway. I will amend the PR.

<!-- gh-comment-id:3311709000 --> @tooxo commented on GitHub (Sep 19, 2025): > I see what you mean now, but I think we should focus on fixing where `err != nil and fetching is true` happens, that's the real bug. The fact that the two nested loops cause a busy loop is the effect of the bug. > > Perhaps we should clear `chunk.err` and `chunk.data` [here](https://github.com/devgianlu/go-librespot/blob/05c1cc8c7bc291b924e5a1537184f826e463ceb2/audio/chunked_reader.go#L153)? Yes this would also be a solution. Clearing chunk.err would be enough, because otherwise the function would have returned at this point anyway. I will amend the PR.
Author
Owner

@devgianlu commented on GitHub (Sep 19, 2025):

This can be closed right?

<!-- gh-comment-id:3311801122 --> @devgianlu commented on GitHub (Sep 19, 2025): This can be closed right?
Author
Owner

@tooxo commented on GitHub (Sep 19, 2025):

yup

<!-- gh-comment-id:3311804436 --> @tooxo commented on GitHub (Sep 19, 2025): yup
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/go-librespot#139
No description provided.