Closed benkuper closed 1 hour ago
the function "update" is called in a dedicated thread at 100fps
Is the JavascriptEngine shared-with or accessed-from the main thread? If so, do you synchronise accesses to the engine in any way?
Assuming the threading is in order, perhaps the problem is to do with JavascriptEngine::maximumExecutionTime. It looks like this used to be initialised to 15 seconds, but is now initialised to zero, which I think was an unintentional change.
I've pushed a potential fix here: https://github.com/juce-framework/JUCE/commit/5453192a0caf0dfbe0222b52eb9f617e04e46c90
Please try it out and let us know if the problem is resolved.
Thank you for the fast update, unfortunately this doesn't make it. I actually have exposed a method to change the timeout and executionTime from the script itself and had suspected already that it may be that. I tested with the latest dev branch (8.0.3 merged with main), same problem..
Is the JavascriptEngine shared-with or accessed-from the main thread? If so, do you synchronise accesses to the engine in any way?
Please could you confirm that you're not accessing the javascript engine from multiple threads? Have you tried testing with Thread Sanitizer just in case?
If there are no threading issues, then a minimal example that demonstrates the problem would be very helpful in tracking down the issue.
I don't see any reason another thread would access it but I can check and confirm.
I feel like the timing of the crash is not so random, actually quite steady over many tests. I'll have to dig further to provide valuable informations but it may be a clue.
I don't know about thread sanitizer but I'll check how to use it.
Thank you !
So I went minimal and created a fresh empty project with this code in Main.cpp :
void initialise (const juce::String& commandLine) override
{
// This method is where you should put your application's initialisation code..
mainWindow.reset (new MainWindow (getApplicationName()));
code = "function test() { for(var i=0;i<1000;i++) { var test = 2; } }";
engine.execute(code);
// engine.maximumExecutionTime = juce::RelativeTime(3); //doesn't change anything
juce::var thisObject = juce::var(new juce::DynamicObject());
juce::var args;
int index = 0;
double time = juce::Time::getMillisecondCounterHiRes() / 1000.0;
while (true)
{
juce::Result result = juce::Result::ok();
engine.callFunction("test", juce::var::NativeFunctionArgs(thisObject, &args, 0), &result);
double t = juce::Time::getMillisecondCounterHiRes() / 1000.0;
DBG(index++ << " / " << (t-time) << " / " << result.getErrorMessage());
juce::Thread::getCurrentThread()->sleep(200);
}
}
Here are all my findings :
So I guess there is something set in the constructor that isn't updated later, and this timeout is checked internally against the last "execute" function time, not the last callFunction time
I hope this helps, I started checking AddressSanitizer but didn't go further as those findings seem already valuable for going further, and discard the thread theory imho
I posted a PR to fix the problem in a simple way, that should at least be good for most use cases. (The first PR was wrongly made against my own dev branch which has many other differences)
Thanks for the additional details. I've pushed a change that should resolve this issue here: https://github.com/juce-framework/JUCE/commit/3cca812d3804b3dbc729685d068428b25b384d3d
Thank you, tested and seems all good !
Detailed steps on how to reproduce the bug
I have this very simple script, the function "update" is called in a dedicated thread at 100fps.
Eventually, this code will stop, the returned error code being "interrupted".
This is the stack trace when breaking at the throwing of this interruption :
In the js_poll_interrupts function, the ctx->interrupt_counter has a value of 10000, same value in multiple runs
changing the loop count to 1 makes it run more before crashing removing the for loop and keeping just the update function seems to be ok, but it could also mean that it would run way more before crashing.
EDIT : I let the script live a bit longer with only the update() function and it ended up crashing as well, same error
What is the expected behaviour?
No interrupt, or at least a more informative error message. But with the minimalism of this code, I'd rather hope for no crash :)
Operating systems
Windows
What versions of the operating systems?
Win 11
Architectures
64-bit
Stacktrace
No response
Plug-in formats (if applicable)
No response
Plug-in host applications (DAWs) (if applicable)
No response
Testing on the
develop
branchThe bug is present on the
develop
branchCode of Conduct