Project

General

Profile

Bug #11393

Updated by nobu (Nobuyoshi Nakada) almost 9 years ago

~~~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`. rb_ensure. 

 1. `PUSH_TAG();` PUSH_TAG(); creates a local `_tag` _tag on the stack, and sets `th->tag` th->tag to 
    
 its address. 
 2. `EXEC_TAG();` EXEC_TAG(); calls `setjmp` setjmp on this `_tag` _tag object 
 3. result = (*b_proc) (data1); fails with LoadError (calls 
    `load_file_internal` 
 load_file_internal with a nonexistent file, intentionally), setting 
    
 state to 6. 
 4. `POP_TAG();` POP_TAG(); resets `th->tag` 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` th->tag is `NULL`, NULL, due to (4) above! So we AV when trying to get `th->tag->buf`. th->tag->buf. 

Back