Closed czkz closed 4 months ago
The issue here seems to be with the os_shell function, and the fact that is implemented to run on a another thread, and then schedule the original fiber when it completes.
The second instance is a bit more complex, as the initial deadline cancellation triggers the second piece of code to run, which should also immediately expire the deadline.
Hard to tell from just the valgrind output, but I think the invalid read is from calling strlen
on a symbol created by (gensym)
. Most function internal to Janet don't require a trailing 0 byte for strings, but all created strings should have such a byte just in case.
@czkz Check now for examples 1 and 3. Example 2 I think should still have some strange behavior, but that is because the construction is strange. I have not yet decided on why the correct behavior here should be - my current thought is that "edefer end" and "main end" should not print, but everything else should.
The issue here seems to be with the os_shell function
Note: replacing os/shell with os/spawn resulted in the same behavior (but both are now fixed).
Check now for examples 1 and 3.
Example 1 is fixed for both os/shell and os/spawn. Example 3 now produces less errors :)
the invalid read is from calling strlen on a symbol created by (gensym)
Indeed! This example triggers the valgrind error (even on the new version):
(ev/cancel
(ev/spawn (ev/sleep 1e9))
(gensym))
It also spits random garbage in the error, e.g.
error: _00000r0Mw\
A
in _spawn [tst2.janet] on line 2, column 13
I have not yet decided on why the correct behavior here should be - my current thought is that "edefer end" and "main end" should not print, but everything else should.
It could work as if edefer body was offloaded to a new fiber. Not necessarily one-to-one, but something similar to this:
(ev/spawn
(ev/deadline 0.1)
(edefer
(ev/spawn # the only line different from example 2
(print "edefer start")
(os/shell "sleep 10 && echo sh_edefer")
(print "edefer end"))
(print "main start")
(os/shell "sleep 5 && echo sh_main")
(print "main end")))
output:
main start
error: deadline expired
edefer start
sh_main
sh_edefer
edefer end
Example 1
A fiber is resumed after it's cancelled.
Output:
Example 2
A fiber with
edefer
can be resumed in the error path by the wait in the normal path. Note thatsh_edefer
is printed afteredefer_end
, which should not be possible.Output (without stacktraces):
Example 3
This one is in a sizable project, and I didn't find the exact cause. It's similar to the second example, but janet error messages look strange, and valgrind finds some kind of undefined behavior. When I remove
edefer
it works fine.I've included it just in case the stacktraces are useful.
Output of "valgrind janet index.janet"
```txt ==1391== Memcheck, a memory error detector ==1391== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==1391== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info ==1391== Command: janet index.janet ==1391==