Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when using IO from finalizer inside Task #21442

Closed
turtleslow opened this issue Apr 19, 2017 · 9 comments · Fixed by #21458
Closed

Crash when using IO from finalizer inside Task #21442

turtleslow opened this issue Apr 19, 2017 · 9 comments · Fixed by #21458
Assignees

Comments

@turtleslow
Copy link

A finalizer which uses print() was called from a Task that was created with @async, resulting in a crash with the following errors:

error in running finalizer: ErrorException("task switch not allowed from inside gc finalizer")
error in running finalizer: ErrorException("schedule: Task not runnable")

WARNING: Workqueue inconsistency detected: shift!(Workqueue).state != :queued
ERROR (unhandled task failure): schedule: Task not runnable
 in enq_work(::Task) at ./event.jl:77
 in yield at ./event.jl:126 [inlined]
 in macro expansion at ./someFile.jl:234 [inlined]
 in macro expansion at ./util.jl:188 [inlined]
 in macro expansion at ./someFile.jl:123 [inlined]
 in someFunction() at ./task.jl:360

fatal: error thrown and no exception handler available.
InterruptException()
jl_run_once at /home/abuild/rpmbuild/BUILD/julia-0.5.1/src/jl_uv.c:142
process_events at ./libuv.jl:82
wait at ./event.jl:147
task_done_hook at ./task.jl:191
unknown function (ip: 0x7fce8ba564e2)
jl_call_method_internal at /home/abuild/rpmbuild/BUILD/julia-0.5.1/src/julia_internal.h:210 [inlined]
jl_apply_generic at /home/abuild/rpmbuild/BUILD/julia-0.5.1/src/gf.c:1950
jl_apply at /home/abuild/rpmbuild/BUILD/julia-0.5.1/src/julia.h:1392 [inlined]
finish_task at /home/abuild/rpmbuild/BUILD/julia-0.5.1/src/task.c:215 [inlined]
start_task at /home/abuild/rpmbuild/BUILD/julia-0.5.1/src/task.c:262
unknown function (ip: 0xffffffffffffffff)
@JeffBezanson
Copy link
Sponsor Member

The error is correct; task switches (which includes most I/O) are not allowed in finalizers.

@JeffBezanson
Copy link
Sponsor Member

One workaround is to @schedule the I/O operation from the finalizer, instead of doing it in the finalizer itself.

@StefanKarpinski
Copy link
Sponsor Member

Can we make it so that all task switches invoked from finalizers automatically schedule the task instead of trying to run inside the finalizer? Wouldn't that typically have the desired effect?

@vtjnash
Copy link
Sponsor Member

vtjnash commented Apr 19, 2017

that's possible, but it would mean wrapping all finalizers in a Task

@StefanKarpinski
Copy link
Sponsor Member

Would it be possible to do it lazily at the time when the finalizer tries to do the switch?

@StefanKarpinski
Copy link
Sponsor Member

Otherwise, it seems fine to just improve the error message here.

@vtjnash vtjnash self-assigned this Apr 19, 2017
@JeffBezanson
Copy link
Sponsor Member

AFAICT the lazy approach would be very hard to implement, since it would require relocating everything in the stack since the call to the finalizer.

@StefanKarpinski
Copy link
Sponsor Member

Ok, in that case, let's just improve the error message to make it clear what the problem is – i.e. that you cannot do I/O or any other task switching from a finalizer, and maybe some kind of bread crumb to how to explicitly schedule a new task from a finalizer.

@turtleslow
Copy link
Author

Thanks for the tip using @schedule.

The above error appeared to place me in a state where the REPL would no longer evaluate what I was typing. The following seems to place me in the same state:

t = @schedule try
    while true; sleep(1); end
end

Base.throwto(t,InterruptException())

After this, it seems like the only thing I could do is hit Ctrl-C, which causes Julia to terminate. Is that the expected behavior? (I'm using 0.5.1)

vtjnash added a commit that referenced this issue Apr 20, 2017
previously we couldn't reliably tell the difference between a failure to context switch
and an explicitly scheduled error

in the former case, we often need to undo some prior action
by moving the code for the later into Julia,
we can reliably run the necessary undo action when required

fix #21442
vtjnash added a commit that referenced this issue Apr 20, 2017
previously we couldn't reliably tell the difference between a failure to context switch
and an explicitly scheduled error

in the former case, we often need to undo some prior action
by moving the code for the later into Julia,
we can reliably run the necessary undo action when required

fix #21442
vtjnash added a commit that referenced this issue Apr 22, 2017
previously we couldn't reliably tell the difference between a failure to context switch
and an explicitly scheduled error

in the former case, we often need to undo some prior action
by moving the code for the later into Julia,
we can reliably run the necessary undo action when required

fix #21442
vtjnash added a commit that referenced this issue Apr 22, 2017
previously we couldn't reliably tell the difference between a failure to context switch
and an explicitly scheduled error

in the former case, we often need to undo some prior action
by moving the code for the later into Julia,
we can reliably run the necessary undo action when required

fix #21442
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants