Duktape not returning control to the executor to check for bytecode execution timeout
See original GitHub issueDuktape Version: 2.3.0
From the docs(https://github.com/svaarala/duktape/blob/master/doc/sandboxing.rst):
“Duktape places on internal sanity limit for some operations, such as regexp execution taking too many steps. When that happens a RangeError is thrown. Although user code can catch such an error, it returns control to the executor so that the bytecode execution timeout can kick in if necessary.”
I am not seeing “returns control to the executor so that the bytecode execution timeout can kick in if necessary” occur. See minimal example below.
#include <stdio.h>
#include "duktape.h"
int duk_exec_timeout(void *udata) {
printf("-");
fflush(stdout);
return 0;
}
static void fatal_handle(void *udata, const char *msg) {
fprintf(stderr, "Error: %s\n", (msg ? msg : "no message"));
fflush(stderr);
abort();
}
int main(int argc, char *argv[]) {
duk_context *ctx = duk_create_heap(NULL, NULL, NULL, NULL, fatal_handle);
char *js = "\
var re = new RegExp('A(B|C+)*DE?');\
while(true) { try { \
re.exec('ACCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC');\
} catch(error) {}}";
duk_eval_string(ctx, js);
duk_destroy_heap(ctx);
return 0;
}
Running the above example, there is only an initial - printed from the timeout check, then we enter the infinite loop to execute regex that causes a RangeError, which is repeatedly caught by the try/catch. My understanding is that the try/catch should be calling into duk_exec_timeout at some point? Removing the loop and the try catch produces the RangeError, and removing just the loop causes the program to finish with no errors, but still not output any additional -'s to indicate checking for a timeout.
Issue Analytics
- State:
- Created 5 years ago
- Comments:9 (6 by maintainers)

Top Related StackOverflow Question
Given the constraints it’s, unfortunately, a natural consequence of the interrupt/timeout mechanism and hard to completely overcome.
For example, even if all Duktape built-in functions were conscious of execution time so that long operations would internally trigger timeout checks, there would still in many cases be application Duktape/C functions that might fail to do the same (assuming an API was added to allow explicit cooperation with a timeout mechanism).
If performance were not a concern one could check for timeout more frequently, even for every opcode or Duktape API call. But in some applications that might be too much - and even with this it may be that a Duktape/C function is blocked for a long time doing something that doesn’t involve the Duktape API at all.
A natural solution would be a timer and some mechanism of interrupting a thread. But such solutions pose relatively hairy portability concerns so they’re not generally very desirable for a portable engine like Duktape.
All that said it’s certainly good to eliminate places where this becomes a concrete issue and maybe add an API where an application may do the same for long running functions. But it’s unlikely the issue can be solved in a completely satisfying manner with minimal portability assumptions.
This indeed is the core problem 😃!
This is okay, I should be able to edit the source manually to play around with this.
Thanks for everyones help!