question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Duktape not returning control to the executor to check for bytecode execution timeout

See original GitHub issue

Duktape 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:open
  • Created 5 years ago
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
svaaralacommented, Oct 11, 2018

The wider issue is that even if individual checks are added here and there, there will always be more operations that take long and don’t invoke the timeout check promptly.

This indeed is the core problem 😃!

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.

  • As a side note, in essence all public API functions have a macro call which would allow one to check for timeouts on every API call if necessary. So this wouldn’t be too difficult to implement except for the performance concerns.

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.

0reactions
JoelScarfonecommented, Oct 11, 2018

The wider issue is that even if individual checks are added here and there, there will always be more operations that take long and don’t invoke the timeout check promptly.

This indeed is the core problem 😃!

unfortunately it’s not exposed through duk_config.h

This is okay, I should be able to edit the source manually to play around with this.

Thanks for everyones help!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Duktape Programmer's Guide
Once script execution is finished, control is returned to your program (the API call returns) and a return value is left on the...
Read more >
content/handlers/javascript/duktape/duktape.c Source File
175 * Source files should not include individual header files, as they ... 8162 * for reasonable execution timeout checking but large enough...
Read more >
duktape - Bountysource
In early development user code often makes Duktape API calls without a ... is integrated into the bytecode executor, and is used for...
Read more >
https://hackage.haskell.org/package/hs-duktape-0.1...
Note that this * does not limit bytecode executor internal call depth at all ... must be small enough to allow * for...
Read more >
A curated list of awesome Go frameworks, libraries and ...
If you see a package or project here that is no longer maintained or is not ... used to control the execution and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found