ruby-changes:53780
From: k0kubun <ko1@a...>
Date: Tue, 27 Nov 2018 00:12:36 +0900 (JST)
Subject: [ruby-changes:53780] k0kubun:r65999 (trunk): process.c: avoid dlclose before exec
k0kubun 2018-11-27 00:12:31 +0900 (Tue, 27 Nov 2018) New Revision: 65999 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=65999 Log: process.c: avoid dlclose before exec because JIT-ed code may still be on stack at this time, unlike in ruby_cleanup(). This hopes to fix: (take 2) http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/1480207 Modified files: trunk/eval.c trunk/internal.h trunk/mjit.c trunk/process.c Index: eval.c =================================================================== --- eval.c (revision 65998) +++ eval.c (revision 65999) @@ -233,7 +233,7 @@ ruby_cleanup(volatile int ex) https://github.com/ruby/ruby/blob/trunk/eval.c#L233 } } - mjit_finish(); /* We still need ISeqs here. */ + mjit_finish(TRUE); /* We still need ISeqs here. */ ruby_finalize_1(); Index: mjit.c =================================================================== --- mjit.c (revision 65998) +++ mjit.c (revision 65999) @@ -134,12 +134,13 @@ init_list(struct rb_mjit_unit_list *list https://github.com/ruby/ruby/blob/trunk/mjit.c#L134 because node of unit_queue and one of active_units may have the same unit during proceeding unit. */ static void -free_list(struct rb_mjit_unit_list *list) +free_list(struct rb_mjit_unit_list *list, int close_handle_p) { struct rb_mjit_unit *unit = 0, *next; list_for_each_safe(&list->head, unit, next, unode) { list_del(&unit->unode); + if (!close_handle_p) unit->handle = NULL; /* Skip dlclose in free_unit() */ free_unit(unit); } list->length = 0; @@ -787,9 +788,12 @@ mjit_child_after_fork(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L788 /* Finish the threads processing units and creating PCH, finalize and free MJIT data. It should be called last during MJIT - life. */ + life. + + If close_handle_p is TRUE, it calls dlclose() for JIT-ed code. So it should be FALSE + if the code can still be on stack. ...But it means to leak JIT-ed handle forever (FIXME). */ void -mjit_finish(void) +mjit_finish(int close_handle_p) { if (!mjit_enabled) return; @@ -827,9 +831,9 @@ mjit_finish(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L831 xfree(pch_file); pch_file = NULL; mjit_call_p = FALSE; - free_list(&unit_queue); - free_list(&active_units); - free_list(&compact_units); + free_list(&unit_queue, close_handle_p); + free_list(&active_units, close_handle_p); + free_list(&compact_units, close_handle_p); finish_conts(); mjit_enabled = FALSE; Index: process.c =================================================================== --- process.c (revision 65998) +++ process.c (revision 65999) @@ -2944,7 +2944,7 @@ rb_f_exec(int argc, const VALUE *argv) https://github.com/ruby/ruby/blob/trunk/process.c#L2944 execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE); eargp = rb_execarg_get(execarg_obj); - if (mjit_enabled) mjit_finish(); /* do not leave files or leak children */ + if (mjit_enabled) mjit_finish(FALSE); /* avoid leaking resources, and do not leave files. XXX: JIT-ed handle can leak after exec error is rescued. */ before_exec(); /* stop timer thread before redirects */ rb_execarg_parent_start(execarg_obj); fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name; Index: internal.h =================================================================== --- internal.h (revision 65998) +++ internal.h (revision 65999) @@ -1634,12 +1634,12 @@ VALUE rb_math_sqrt(VALUE); https://github.com/ruby/ruby/blob/trunk/internal.h#L1634 extern int mjit_enabled; VALUE mjit_pause(int wait_p); VALUE mjit_resume(void); -void mjit_finish(void); +void mjit_finish(int close_handle_p); #else #define mjit_enabled 0 static inline VALUE mjit_pause(int wait_p){ return Qnil; } /* unreachable */ static inline VALUE mjit_resume(void){ return Qnil; } /* unreachable */ -static inline void mjit_finish(void){} +static inline void mjit_finish(int close_handle_p){} #endif /* newline.c */ -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/