ZeroBraneStudio icon indicating copy to clipboard operation
ZeroBraneStudio copied to clipboard

Step over from a coroutine doesn't step over

Open robertlzj opened this issue 7 years ago • 7 comments

See demo and comment bellow

function Wrap(func,...)
    local coroutine=coroutine.wrap(function(...)
        coroutine.yield()
        return func(...)
    end)
    coroutine(...)
    return coroutine
end
function d()
    require('mobdebug').on()
    coroutine.yield(true)
end
function c()
    return Wrap(d)
end
function b()
    for _ in c() do
    end
end
function a()
    b() --1. Set a breakpoint here, then 'Step over' which should jump to the 'return' bellow, but which not..
    return
end
a()

And there is some other problem, which will bring 'step' into 'mobdebug.lua', but now I can‘t reproduce it, I think it's related with 'for'.

robertlzj avatar Oct 23 '16 03:10 robertlzj

I need to do a more detailed analysis, but it seems like this issue is a side effect of how the step over is implemented. Since during step over the debugger only "remembers" the current stack level and the stack level may change when the control changes between coroutines, this doesn't work correctly if the level inside the coroutine you are stepping into is deeper than in the fragment you made "step over" call. If I'm correct about this issue, there is no simple fix as I'll probably need to change the debugger to keep track of stack levels per context/coroutine and check for the match with a particular coroutine.

pkulchenko avatar Oct 24 '16 00:10 pkulchenko

Oh, bad news.. It seems the problem also happen to 'step into'. I use 'iup', sometimes step into will goes 'into' it, shows:

Couldn't activate file 'C:\Users\rober\Documents\Lua\iuplua.lua' for debugging; continuing without it.

Where "iuplua.lua" didnt exist, which should be a 'dll' by "require 'iuplua'". And at this time current 'step' is disappear, which might run inside 'iuplua.lua'. Also the stack shows:

xx at line yy (defined at [string "iuplua.lua"]: zzz)

Press any step xxx is actually work 'inside', I have to wait it jump back, however cant use 'Step out' in some case, it will jump out from my code, not only from the 'inside' level , but far from it.

Like the problem I mentioned above:

And there is some other problem, which will bring 'step' into 'mobdebug.lua', but now I can‘t reproduce it, I think it's related with 'for'.

robertlzj avatar Oct 24 '16 00:10 robertlzj

This issue also affects stepping out of a coroutine for the same reason.

pkulchenko avatar Feb 24 '18 19:02 pkulchenko

I'm suffocated again at another long long code. After I extract issue demo, I found similar to this one.

function f()
	require("mobdebug").on()
	--	necessary condition
	for _ in pairs{} do
		--	necessary condition
		coroutine.yield(_)
	end
end
coroutine.wrap(f)()
print'Break here'
print'Shold run here if choose step over from above line.'
print'But actually run till the end / next break point as choosed step out.'

I'm not sure if they are essentially the same.

robertlzj avatar Jul 06 '18 07:07 robertlzj

Yes, I think it's the same issue and would be addressed by the same solution (having a per-thread stepping).

pkulchenko avatar Jul 06 '18 07:07 pkulchenko

Eh... walk around solution. 😥

robertlzj avatar Jul 06 '18 07:07 robertlzj

I have some wrapped enumerator like pairs() using coroutine. There is some level between the enumerator and active run line. So, I often lose step accidentally - I use step, but code run till end (for no breakpoint stop it), even if the coroutine during process is finished (not yield temporarily).

I'm not understand the solution above "having a per-thread stepping". I have to put breakpoint next nearly after current step position?

I find disable/comment require("mobdebug").on() will avoid this issue (partially?). This is workable which I could disable debug on the enumerator (coroutine) after it pass test reliably.

robertlzj avatar Jul 19 '18 08:07 robertlzj