mini_racer: global exception management

My players have written JS that looks like the following:

function(context, args)
{
    var o={};
    o.__defineGetter__('bar',function(){

        for(var i=0;i<10;++i)
            some_rb_attached_method({data:"foo"});
        return 2
    });
    return o
}

which gets evaluated after the .eval() block on the context. e.g:

result = ctx.eval(above_code)
ctx.stop
ActiveSupport::JSON.encode(result) # or something similar

This will throw a c-extension exception in mini_racer /mini_racer.rb:96: [BUG] rb_thread_call_with_gvl: called by a thread which has GVL.

I can fix this error (several solutions), but what I really want is to be able to catch these and log them somehow on the server, so that I can fix them. Right now I think they disappear into the void.

Ideally, I’d like this code to be safe, (catch in c, safe & consistent log, and rethrow; to terminate if it’s a fatal issue)

Any thoughts?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 26 (10 by maintainers)

Commits related to this issue

Most upvoted comments

@seanmakesgames: one thing I can think of is reading stderr of the process in question, and checking for the substring [BUG], or any other weird output. That would at least let you trigger an alert. I think segfaults aren’t really a recoverable state, so there might not be a same-process way to check for such errors.

@SamSaffron: :salute:.

The second error seems to only occur when calling an external function from a getter inside the final JS-to-Ruby conversion. If I change the JS to o = {get bar() { print(42); }}; o.bar; 1, it successfully prints “42” and “1”. Similarly, changing the final statement to JSON.parse(JSON.stringify(o)) renders it safe for the conversion code.

Hmm… thinking about general applications (i.e., including things other than Sean’s game)… external functions inside getters within JS could be useful, but they don’t need to be available at the JS-Ruby boundary. Is there some way to block external functions specifically in that final JS-to-Ruby statement?