Possible mruby bug in mrb_load_string #894

GarthyD opened this Issue Feb 26, 2013 · 2 comments


None yet
3 participants

GarthyD commented Feb 26, 2013

I have been having a bit of a play around with mruby (note: mruby, not MRI Ruby), and I believe I may have found a bug in a recent (20130222) version.

Basically, if you call mrb_load_string with something that returns a class, then make a call on the returned object that throws an exception, and then call mrb_load_string with a string that makes the same kind of return, the class in question has somehow vanished from the environment, and the second load will fail.

Test program and Makefile below. The test string is simply "Float", which returns the Float class. The first time it calls it, it is okay. The second time, "Float" no longer exists.

Naturally, if you remove the call to 'dummyCall', the second load works as it should.

I have seen the problem with other classes as well, although the specifics of what triggers the problem can vary. It is hard to make a general statement as to the exact fault. As a general rule, if any Class is returned from mrb_load_string, and a subsequent call on the return generates an exception, depending on what you do, the whole Class may or may not (seem to) be removed from the current environment.

I can't guarantee my code below is bug-free- I'm still fairly new to mruby. It is possible I have made an incorrect assumption in the code below. If not, it looks like a mruby bug.

I am using mruby as checked out on 20130222 (22/2/13), Linux, Debian, 64-bit. Can supply additional information if needed.


include <mruby.h>

include <mruby/compile.h>

include <mruby/string.h>

include <assert.h>

include <string.h>

static void show_result(mrb_state *mrb, mrb_value v)
switch (mrb_type(v))
fprintf(stderr, "- Type Class returned.\n");
fprintf(stderr, "- Type false/nil returned.\n");
fprintf(stderr, "- Type %d returned.\n", mrb_type(v));

if (mrb->exc)
struct RObject *exc = mrb->exc;
mrb->exc = 0;
mrb_value e = mrb_obj_value(exc);
mrb_value e_to_s = mrb_funcall(mrb, e, "to_s", 0);
assert(mrb->exc == 0);
if (mrb_type(e_to_s) == MRB_TT_STRING)
char buff[512];
memcpy(buff, RSTRING_PTR(e_to_s), RSTRING_LEN(e_to_s));
buff[RSTRING_LEN(e_to_s)] = '\0';
fprintf(stderr, "- Exception was: %s\n", buff);
fprintf(stderr, "- Exception could not be identified.\n");
assert(mrb->exc == 0);
fprintf(stderr, "- No exception.\n");

int main(int argc, char *argv[])
mrb_state *mrb = mrb_open();

fprintf(stderr, "Loading first string:\n");
mrb_value v1 = mrb_load_string(mrb, "Float");
show_result(mrb, v1);

fprintf(stderr, "Making bad call:\n");
mrb_value v2 = mrb_funcall(mrb, v1, "dummyCall", 0);
show_result(mrb, v2);

fprintf(stderr, "Loading same string again. Should work, but doesn't.\n");
mrb_value v3 = mrb_load_string(mrb, "Float");
show_result(mrb, v3);

return 0;


floatnom: floatnom.o
gcc -o floatnom floatnom.o -L/path/to/mruby/lib -lmruby -lm

floatnom.o: floatnom.c
gcc -Wall -o floatnom.o -I/path/to/mruby/include -c floatnom.c

rm -f floatnom floatnom.o

Typical output

(May be typos- transcribed by hand)

Loading first string:

  • Type Class returned.
  • No exception.
    Making bad call:
  • Type false/nil returned.
  • Exception was: undefined method 'dummyCall' for Float
    Loading same string again. Should work, but doesn't.
  • Type false/nil returned.
  • Exception was: uninitialized constant Float

This comment has been minimized.

Show comment Hide comment

mattn Feb 26, 2013


This issue will be closed with #890


mattn commented Feb 26, 2013

This issue will be closed with #890

cremno added a commit to cremno/mruby that referenced this issue Feb 26, 2013

This comment has been minimized.

Show comment Hide comment

matz Feb 27, 2013


closed by #890


matz commented Feb 27, 2013

closed by #890

@matz matz closed this Feb 27, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment