How to debug in coroutine(task)?

Recently, when I develop, the process output nothing. Then with using @show I found bug in the code of task(coroutine).
Does anyone knows if there be some tools or methods to debug in coroutine(task)?

It may be that @show is what triggers the task to display its result.

You might also be able to achieve the same thing with wait(t)

Thanks for your answer!
May be I described not clear enough.
I mean,
I wrote the program with Juilalang.
And it have one routine, being started with @async.
It run, but without correct output.
Finally, with @show, I debugged it, step by step.
Is there other tools or methods, to debug program like this easier?

Thanks again!

Ah, I understand.

If you are using VS-Code, perhaps you can use the debugger? Documentation is here: Debugging · Julia in VS Code

It looks as if the debugger does not work inside async tasks, based on this issue: https://github.com/JuliaDebug/JuliaInterpreter.jl/issues/413

Is there a way you could extract your code into a function, and then call the function normally (without async) to use the debugger?

1 Like

Debugging tasks can be quite challenging. I used to have this prototype project where the tasks, spawned a task which spawned a task. It was a bad design, but for purposes to get it done, I found that redefining the @async macro like:

import Base.sync_varname
import Base.@async

macro async(expr)

    tryexpr = quote
        try
            $expr
        catch err
            @warn "error within async" exception=err # line $(__source__.line):
            @show stacktrace(catch_backtrace())
        end
    end

    thunk = esc(:(()->($tryexpr)))

    var = esc(sync_varname)
    quote
        local task = Task($thunk)
        if $(Expr(:isdefined, var))
            push!($var, task)
        end
        schedule(task)
        task
    end
end

works quite well while debugging.

From my limited experience, and this really is a matter of opinion, a good strategy is also to test the spawned function separately. To do that, it helps to use channels for IO. For instance, reading a string from a socket can be refactored into reading byte string from a Channel, which is easier to test. In addition to avoiding introducing more tasks, one can subtype AbstractChannel, and that way insert a code dealing with the IO object.

Another thing that helps in debugging tasks is reformulating the logic in communicating finite state machines. Something like:

newstate, newmsg = step(state, msg)

works quite well with Julia’s multiple dispatch mechanism. This design also goes hand in hand with the ability to notify condition condition = Threads.Condition() with a value like:

notify(condition, state)

enabling to debug the code within the task without using the @show method.

2 Likes

Thank you very much!

Thank you! You are the first julia master I have communicated with.

1 Like