[#70257] [Ruby trunk - Feature #11420] [Open] Introduce ID key table into MRI — ko1@...

Issue #11420 has been reported by Koichi Sasada.

11 messages 2015/08/06

[ruby-core:70208] [Ruby trunk - Bug #11393] [Third Party's Issue] segfault on trivial application, embedding in C app.

From: nobu@...
Date: 2015-08-01 02:14:33 UTC
List: ruby-core #70208
Issue #11393 has been updated by Nobuyoshi Nakada.

Description updated
Status changed from Open to Third Party's Issue

In short; use `rb_protect()`.

Ruby interpreter can't deal with exceptions raised outside its scope.
So you **must do it by yourself** instead.

~~~c
#include <ruby.h>

static VALUE
load_file(VALUE name)
{
    return (VALUE)rb_load_file((const char *)name);
}

int
main(void)
{
    int state;
    ruby_setup();
    rb_protect(load_file, (VALUE)"abc", &state);
    ruby_cleanup(0);
    if (state) {
        fprintf(stderr, "load failed\n");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
~~~

I'm not sure what you want to do with `rb_load_file`, though.
It just parses a script but evaluates nothing.



----------------------------------------
Bug #11393: segfault on trivial application, embedding in C app.
https://bugs.ruby-lang.org/issues/11393#change-53633

* Author: Alex Budovski
* Status: Third Party's Issue
* Priority: Normal
* Assignee: 
* ruby -v: 2.2.2
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
~~~c
#include <ruby.h>
#include <stdio.h>
int main()
{
	ruby_setup();
	rb_load_file("abc");  // AV here
	ruby_cleanup(0);
}
~~~

~~~
  rbtest1.exe!rb_vm_bugreport(const void * ctx) Line 1024 C
  rbtest1.exe!rb_bug_context(const void * ctx, const char * fmt, ...) Line 422 C
  rbtest1.exe!sigsegv(int sig) Line 887 C
  [External Code]
  rbtest1.exe!rb_threadptr_tag_jump(rb_thread_struct * th, int st) Line 163 C
> rbtest1.exe!rb_ensure(unsigned __int64 (...) * b_proc, unsigned __int64 data1, unsigned __int64 (...) * e_proc, unsigned __int64 data2) Line 915 C
  rbtest1.exe!load_file(unsigned __int64 parser, unsigned __int64 fname, int script, cmdline_options * opt) Line 1779 C
  rbtest1.exe!rb_load_file_str(unsigned __int64 fname_v) Line 1794 C
  rbtest1.exe!rb_load_file(const char * fname) Line 1786 C
  rbtest1.exe!main() Line 7 C++
~~~

Tried using both stable 2.2.2 and git master
f965866f4f0a00c8179a1097e89fb4e61f71a92a

Win Server 2012 R2, VS 2013 Update 4. x64.

The AV was due to the following sequence of events, all revolving
around `rb_ensure`.

1. `PUSH_TAG();` creates a local `_tag` on the stack, and sets `th->tag` to
   its address.
2. `EXEC_TAG();` calls `setjmp` on this `_tag` object
3. result = (*b_proc) (data1); fails with LoadError (calls
   `load_file_internal` with a nonexistent file, intentionally), setting
   state to 6.
4. `POP_TAG();` resets `th->tag` to NULL.
5.  

    ~~~c
    if (state)
    	JUMP_TAG(state);
    ~~~

    executes, looks up the current thread, and tries to jump to

    ~~~c
        ruby_longjmp(th->tag->buf, 1);
    ~~~

    but `th->tag` is `NULL`, due to (4) above! So we AV when trying to get `th->tag->buf`.




-- 
https://bugs.ruby-lang.org/

In This Thread

Prev Next