I am trying to have a while loop in my on_input that will continuually execute piece of code every few seconds
while(action_id == hash("click"))
do
print("Going")
end
I have tried moving it into other functions that are called by on_input, but every time a run this piece of code it crashes the program.
EDIT: I found that I was supposed to make sure the condition becomes false, stupid mistake.
The on_input() function is called by the engine every frame that some kind of input is received. What you are doing is entering an infinite loop during the frame when you receive an action_id that is "click". The loop will never complete since action_id will not change and the engine will lock up.
I just needed to make sure the conditional is false. I initially thought that the while loop would simply execute and then execute, this should have been done by an if statement.
Related
This is my code
https://pastebin.com/fnZreFKA
I have tried all the coroutine options, I have print statements at the start of each of the two functions, it prints, but it doesn't do anything in the loop
coroutine.wrap(constantWork)()
coroutine.wrap(lookForKeys)()
The loops start after line 170
Because they are not detached threads, they are green synchronous threads, only one of them will run the code at the time.
To simulate multitasking you forgot to use yield. coroutine.yield pauses the thread and runs the next code after you called the coroutine. You can resume the coroutine later on by calling wrapped coroutine again or using coroutine.resume if you created it using coroutine.create.
Read the documentation here: https://www.lua.org/pil/9.html
coroutine.wrap creates a new coroutine based on the function you passed it, and then creates a new function based on the coroutine. The first time you call it, it calls the original function until it yields. The next time, it returns from the yield and runs until the next yield. And so on.
In ComputerCraft, yielding is the same as waiting for an event.
ComputerCraft comes with the parallel library which runs two or more functions as coroutines in parallel. It does all the work for you.
You can use parallel.waitForAll or parallel.waitForAny, depending on when you want it to return.
Usage: parallel.waitForAll(constantWork, lookForKeys)
I'm trying to do something a little fancy here, but the docs suggest it should be possible. Maybe LLDB is still too new, but I'm getting a lot of debugger crashes / deadlocks and even when that doesn't happen it does't seem to work like I expected.
I'm trying to put together a debug wrapper around all selector calls, to extract the message call graph inside a certain chunk of code. (I could explain why if you really want to know, but it isn't really relevant to the debugger issue.)
I start out with an Xcode breakpoint on the line where I want to start tracking things (for bonus points, this is happening on a secondary thread, but before you ask, no, nothing on any other thread is doing any accesses to this object or anything in its property subgraph):
[myObject startProcessing];
The breakpoint triggers, and I run "bt", just to extract:
* thread #5: tid = 0x2203, 0x000277d2 .........
I then do something mildly evil: I put a breakpoint in objc_msgSend, right at the instruction where it calls out to the real object selector. objc_msgSend looks like:
libobjc.A.dylib`objc_msgSend:
...(instructions)...
0x37babfa4: bx r12
...(more instructions)...
(Actually there are two bx calls but let's keep things simple.) I run:
breakpoint set -a 0x37babfa4 -t 0x2203
(TID included because I'm having enough trouble tracking this one thread and I don't need irrelevant stuff interfering.)
Here's where the scripting comes in. The setup described above works exactly as I'd like it to. If I resume execution until the breakpoint triggers, I can run:
frame select 0
thread step-inst -m this-thread 5
frame info
continue
and the effect will be that the debugger:
moves to the objc_msgSend frame
steps by one instruction, advancing it into the object selector frame it was pointing at
displays relevant details (object type, selector called)
resumes execution
at which point I can keep pasting in those four commands over and over and copying the output until I hate myself.
If, on the other hand, I run:
breakpoint command add -s command
and paste in those exact same commands, everything breaks. It does not advance to the object selector frame. It doesn't show the frame details, or at least not the correct ones -- depending on various tweaks (see below), it may or may not show "objc_msgSend" as being the current function. It doesn't resume execution.
In this case, if I could get that example working, I'd be mostly happy. But for even more bonus points, I've also tried this with python, which I would prefer because it would allow for much more sophisticated logging:
breakpoint command add -s python
> thread = frame.GetThread()
> thread.StepInstruction(1)
> newFrame = thread.GetFrameAtIndex(0)
> print " " * thread.GetNumFrames() + newFrame.GetFunctionName()
> process = thread.GetProcess()
> process.Continue()
> DONE
Again no good. Again depending on tiny details, this may or may not print something (usually objc_msgSend), but it never prints the correct thing. It never steps the instruction forward. It never resumes execution afterwards.
And again, the python version works fine if I do it by hand: if I wait till the breakpoint fires, then run "script" and enter those exact same lines, it works as expected. Some parts will even work in isolation, e.g. if I remove everything except the parts that get the process and call process.Continue() and trigger those automatically, that "works" (meaning I see the lldb prompt flashing rapidly as it suspends and resumes execution. Usually I regret this because it becomes unresponsive and crashes shortly after.)
So: Any ideas? Is the technology Not Ready Yet, or am I just missing some clever piece of the puzzle that will fix everything? Or should I give up entirely and just live with the fact that there are some parts of object internals that I will never understand?...
Breakpoint commands cannot resume execution and then get control back again, at least today. There are a lot of unresolved questions about what would happen if breakpoint 1 is running the process and then breakpoint 2 is hit. Besides the whole question of whether the code base can really handle nested breakpoints correctly (it was designed to...), what does it mean if breakpoint 2 decides execution should stop? Is breakpoint 1's state thrown away?
It seems a little esoteric to worry about a breakpoint hitting another breakpoint while stepping the inferior process but unless all the details have been worked out, it's easy for the user to shoot themselves in the foot. So for today, breakpoint commands can either stop when the breakpoint is hit or continue to run - but there isn't any ability to run a little bit and do more processing. I know this would be a really useful capability for certain tasks but there are a lot of gotchas that need to be thought out before it could be done.
For some cases, it is possible to handle it the other way around ... if you want to stop in function parser() only when it has been called by function lexer(), it is easy to put a breakpoint on lexer() with some a few python commands to go one stack frame up the stack and see what the calling function is. If it's not lexer(), continue. I don't think this will apply to what you're trying to do, though.
This is a long standing source of frustration, but maybe there is something I'm missing. If i'm in the middle of debugging, and I want to exit the debugger and return to IRB or Rails Console, "quit" won't work as it will exit IRB. "finish" also seems to have the same effect as continue. Using "delete" to remove breakpoints and then trying "continue" or "finish" doesn't work.
Any ideas?
At least in byebug, you can do this:
eval return
Which has the net effect of evaluating a return statement from the current function. That works sometimes, depending on how the call stack looks.
Now while this doesn't remove the current breakpoint .... if you just want control back, this will do that in most cases, depending on how your code is structured.
It also is useful to do this when creating a debug entry in your code:
byebug unless $continue
So if all else fails in a debugging session, you can always run
$continue = true
c
Now this opens up a whole set of possibilities.
This SO question has a few good suggestions. It deals with specifically with debugging inside of loops. One great solution is to set the break point outside the loop, then from irb set it inside the loop and clear it manually when you want to.
Basically it comes down to putting a little bit of thought into where you set your breakpoints.
Other than that there doesn't appear to be anything else you can do.
I'm writing a GUI that's meant to be easily customizable by the end-users. The functions are in C++ and are called from Lua. I'm trying to make a Sleep() type function that will pause the script but not the program itself.
I was able to get it working by using threads and making one for each function. However, I want it to be an individual function. As in, instead of having it part of the CreateButton function and every other function, simply having a Delay or Sleep function that only halts the script, not the entire program.
Me being a novice at Lua, I really don't know how to go about this. Any help is appreciated.
I'd look into making a state machine using coroutines and message passing. Treat each button push like a c++ string that gets passed into coroutine resume. You can then build a little state machine that switches on the message. You can then do some UI work and then put the coroutine back to sleep till something sends it another message.
This is pretty handy if you have a state machine that does UI.
pseudo code:
c_obj:wait_for_message("mouse_down");
local message = coroutine.yield();
if(message == "mouse_down") then
update draw function.
end
c_obj:wait_for_message("mouse_up");
local message = coroutine.yield();
if(message == "mouse_up") then
Update UI..
update draw function.
end
etc...
To make your busy-waiting solution more efficient, how about using select() or similar to wait for some GUI events to process, rather than spinning? It seems like something you would need to do in the GUI regardless of the scripting side of things.
When I'm debugging something that goes wrong inside a loop, say on the 600th iteration, it can be a pain to have to break for every one. So I tried setting a conditional breakpoint, to only break if I = 600. That works, but now it takes almost a full minute to reach that point, where before it was almost instantaneous. What's going on, and is there any way to fix it?
When you hit a breakpoint, Windows stops the process and notifies the debugger. It has to switch contexts, evaluate the condition, decide that no, you don't want to be notified about it, restart the process and switch back. That can take a lot of processor cycles. If you're doing it in a tight loop, it'll take a couple orders of magnitude more processor cycles than one iteration of the loop takes.
If you're willing to mess with your code a little, there's a way to do conditional breakpoints without incurring all this overhead.
if <condition here> then
asm int 3 end;
This is a simple assembly instruction that manually sends a breakpoint notification to the OS. Now you can evaluate your condition inside the program, without switching contexts. Just make sure to take it out again when you're done with it. If an int 3 goes off inside a program that's not connected to a debugger, it'll raise an exception.
It slows it down because every time you reach that point, it has to check your condition.
What I tend to do is to temporarily create another variable like this (in C but should be doable in Delphi).
int xyzzynum = 600;
while (true) {
doSomething();
if (--xyzzynum == 0)
xyzzynum = xyzzynum;
}
then I put a non-conditional breakpoint on the "xyzzynum = xyzzynum;" line.
The program runs at full speed until it's been through the loop 600 times, because the debugger is just doing a normal breakpoint interrupt rather than checking conditions every time.
You can make the condition as complicated as you want.
Further to Mason's answer, you could make the int 3 assember only be compiled in if the program is built with the debug conditional defined:
{$ifdef debug}
{$message warn 'debug breakpoint present in code'}
if <condition here> then
asm int 3 end;
{$endif}
So, when you are debugging in the ide, you have the debug conditional in the project options. When you build the final product for your customers (with your build script?), you wouldn't include that symbol, so it wont get compiled in.
I also included the $message compiler directive, so you will see a warning when you compile letting you know that the code is still there. If you do that everywhere you use int 3, you will then have a nice list of places which you can double click on to take you straight to the offending code.
N#
Mason's explanations are quite good.
His code could be made a bit more secure by testing that you run under the debugger:
if (DebugHook <> 0) and <your specific condition here> then
asm int 3 end;
This will not do anything when the application is running normally and will stop if it's running under the debugger (whether launched from the IDE or attached to the debugger).
And with boolean shortcut <your specific condition here> won't even be evaluated if you're not under the debugger.
Conditional breakpoints in any debugger (I'm just surmising here) require the process to flip back and forth every time between your program and the debugger every time the breakpoint is hit. This process is time consuming but I do not think there is anything you can do.
Normally condition breakpoints work by inserting the appropriate break instruction into the code and then checking for the conditions you have specified. It'll check at every iteration and it might well be that the way in which the check is implemented is responsible for the delay as it's unlikely that the debugger compiles and inserts the complete check and breakpoint code into the existing code.
A way that you might be able to accelerate this is if you put the condition followed by an op with no side effect into the code directly and break on that op. Just remember to remove the condition and the op when you're done.