New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement VM timeout #5426
Comments
I am also interested in this topic. In the past, I tried to add a pseudo-interrupt feature with polling to the mruby VM, and use that feature to implement It would be great if it could be ported to various architectures without any performance loss. |
So I can't come up with a trick that doesn't require to to add an opcode counter and a check & (unlikely) branch, so enabling it will add some overhead, but it should not be as high as 10%. Where I really need this is for webassembly, where there really is no other way to avoid freezing without it... |
If you enable and set debug hook - you have callback from VM after every opcode. |
Did this simple test with an opcode_counter, and it works, except mrb->exc is still NULL, so I am probably not diff --git a/src/vm.c b/src/vm.c
index 0665634e..444b3524 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1061,7 +1061,13 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb
#ifdef MRB_USE_DEBUG_HOOK
#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs));
#else
-#define CODE_FETCH_HOOK(mrb, irep, pc, regs)
+
+// #define CODE_FETCH_HOOK(mrb, irep, pc, regs)
+#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if(opcode_counter++ == 1000) { \
+ mrb->jmp = prev_jmp; \
+ MRB_THROW(prev_jmp); \
+}
+
#endif
#ifdef MRB_BYTECODE_DECODE_OPTION
@@ -1156,6 +1162,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc)
uint16_t b;
uint16_t c;
mrb_sym mid;
+ uint32_t opcode_counter = 0;
const struct mrb_irep_catch_handler *ch;
#ifdef DIRECT_THREADED |
This worked better; #define CODE_FETCH_HOOK(mrb, irep, pc, regs) if(opcode_counter++ == 10000) { \
mrb_raise(mrb, mrb->eException_class, "Timeout"); \
} |
If you expand the idea, you can do concurrency processing with a single thread.
Regarding concurrency processing, as a constraint of mruby VM, it is not possible to straddle methods by C functions, so the issue is what to do about that. # The C function can be pseudo-resumed using |
For non threaded or bare bones environments it would be good to be able to set a timeout for the VM, such that a TimeOut exception is throw after a specified number of milliseconds or opcodes.
Otherwise a simple
while true end
would require manually killing the process or even reboot.I will probably patch
mrb_vm_exec()
for this myself in my project, but I think its something that is useful for others as well.The text was updated successfully, but these errors were encountered: