sustrik / libdill

Structured concurrency in C
MIT License
1.68k stars 156 forks source link

hclose() descriptor while there is a bundle_wait() in it #215

Open jcarrano opened 2 years ago

jcarrano commented 2 years ago

Question

Is it legal to issue a hclose() a bundle while at the same time there is a coroutine waiting (with bundle_wait()) on the same bundle?

Situation

From main() start a bundle and an additional "killer" coroutine that will eventually call hclose() on that bundle (it waits on a signalfd). Then main blocks with bundle_wait() on the bundle. When the bundle is closed by the killer main unblocks and everything seems to work, but Valgrind reports a use-after-free.

From the docs it is not clear if this usage is valid. If not, how would one handle this use case? Use channels?

Valgrind output

==80202== Invalid write of size 8
==80202==    at 0x487F501: dill_bundle_wait (cr.c:144)
                      .... etc ....
==80202==    by 0x114B59: run_daemon (main.c:177)
==80202==    by 0x114E19: main (main.c:253)
==80202==  Address 0x4c955a0 is 32 bytes inside a block of size 48 free'd
==80202==    at 0x484827F: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==80202==    by 0x487F41D: dill_bundle_close (cr.c:127)
==80202==    by 0x4880DD6: dill_hclose (handle.c:155)
==80202==    by 0x114954: signal_listener (main.c:105) <- This is  a couroutine
==80202==    by 0x114C94: run_daemon (main.c:166)
==80202==  Block was alloc'd at
==80202==    at 0x4845899: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==80202==    by 0x487F2DA: dill_bundle (cr.c:101)
==80202==    by 0x487F9F5: dill_prologue (cr.c:258)
                      .... etc ....
==80202==    by 0x114A62: run_daemon (main.c:141)
==80202==    by 0x114E19: main (main.c:253)
==80202==