beanshell2
beanshell2 copied to clipboard
breaking infinite loops in beanshell scripts
Find a way to break infinite loops.
Hi,
In our environment we run arbitrary beanshell scripts developed by our
customers.
If one of the scripts is buggy, it may fall into a infinite loop, which blocks
our application and make it hang. And ... this will happen because it is
possible.
So it is critical for us to prevent beanshell scripts from running in an
infinite loop.
My first try, to run the script in separate thread, monitored by another
thread, failed because the new generated thread does not contain all
threadlocal variables/settings/flags from the main thread.
So I could not do for example EJB calls from the new thread because it was
instantiated by the other (main) thread. (the script runs in JBOSS
environment).
Now I took the source bsh-2.1b6 and had a closer look at it.
Every loop finally breaks down to a if statement that evaluates the condition.
What I did now was:
- modified Interpreter.java with a methods
setTimeoutInSeconds() invoked from caller before eval()
checkTimeoutExpiration()
setStartTime() called from eval( String statements ) upon invocation
- modified BSHIfStatement.java the evaluateCondition() method calls a
Interpreter.checkTimeoutExpiration() which looks for the topmost Interpreter
parent and checks, if the timeout expired, if any was set.
If yes, throw EvalError()
Because it is critical for us to have this under control, we approve the
minimal perfomance impact.
I described here what I did because I find it important to have this under
control, to prevent infinite loops. This only works for loops and does not
break any ongoing input/output operation.
What do you think?
Would it be possible that you assembled a mechanism like this in the beanshell
source code?
Regards
Hubert
Original issue reported on code.google.com by hugibertus on 9 Feb 2012 at 9:54
This is a general issue for script languages on the JVM, which are often used
as you describe.
When I looked at JSR-223 when it was published I was disappointed that this
issue was not addressed (as many others).
One workaround would be using the Thread interrupt state for this. Then you
have to start a parallel Thread with is just doing a sleep for the desired
maximum execution time. The first finished task (sleeping or script execution)
will then interrupt the Thread of the other task. And in Interpreter the
interrupt state of the current Thread is checked and if it is set, an
ExecutionException is thrown.
Downside is that some API fail miserably when threads are interrupted...
Original comment by [email protected] on 9 Feb 2012 at 10:42
It seems issue #76 is for the same feature. Link it here. Let's find a proper
and common way to achieve this...
Original comment by [email protected] on 11 Oct 2012 at 7:32