1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65999 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
k0kubun 2018-11-26 15:12:31 +00:00
parent 5b12501163
commit 98a2b053f8
4 changed files with 14 additions and 10 deletions

2
eval.c
View file

@ -233,7 +233,7 @@ ruby_cleanup(volatile int ex)
} }
} }
mjit_finish(); /* We still need ISeqs here. */ mjit_finish(TRUE); /* We still need ISeqs here. */
ruby_finalize_1(); ruby_finalize_1();

View file

@ -1634,12 +1634,12 @@ VALUE rb_math_sqrt(VALUE);
extern int mjit_enabled; extern int mjit_enabled;
VALUE mjit_pause(int wait_p); VALUE mjit_pause(int wait_p);
VALUE mjit_resume(void); VALUE mjit_resume(void);
void mjit_finish(void); void mjit_finish(int close_handle_p);
#else #else
#define mjit_enabled 0 #define mjit_enabled 0
static inline VALUE mjit_pause(int wait_p){ return Qnil; } /* unreachable */ static inline VALUE mjit_pause(int wait_p){ return Qnil; } /* unreachable */
static inline VALUE mjit_resume(void){ 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 #endif
/* newline.c */ /* newline.c */

16
mjit.c
View file

@ -134,12 +134,13 @@ init_list(struct rb_mjit_unit_list *list)
because node of unit_queue and one of active_units may have the same unit because node of unit_queue and one of active_units may have the same unit
during proceeding unit. */ during proceeding unit. */
static void 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; struct rb_mjit_unit *unit = 0, *next;
list_for_each_safe(&list->head, unit, next, unode) { list_for_each_safe(&list->head, unit, next, unode) {
list_del(&unit->unode); list_del(&unit->unode);
if (!close_handle_p) unit->handle = NULL; /* Skip dlclose in free_unit() */
free_unit(unit); free_unit(unit);
} }
list->length = 0; list->length = 0;
@ -787,9 +788,12 @@ mjit_child_after_fork(void)
/* Finish the threads processing units and creating PCH, finalize /* Finish the threads processing units and creating PCH, finalize
and free MJIT data. It should be called last during MJIT 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 void
mjit_finish(void) mjit_finish(int close_handle_p)
{ {
if (!mjit_enabled) if (!mjit_enabled)
return; return;
@ -827,9 +831,9 @@ mjit_finish(void)
xfree(pch_file); pch_file = NULL; xfree(pch_file); pch_file = NULL;
mjit_call_p = FALSE; mjit_call_p = FALSE;
free_list(&unit_queue); free_list(&unit_queue, close_handle_p);
free_list(&active_units); free_list(&active_units, close_handle_p);
free_list(&compact_units); free_list(&compact_units, close_handle_p);
finish_conts(); finish_conts();
mjit_enabled = FALSE; mjit_enabled = FALSE;

View file

@ -2944,7 +2944,7 @@ rb_f_exec(int argc, const VALUE *argv)
execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE); execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE);
eargp = rb_execarg_get(execarg_obj); 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 */ before_exec(); /* stop timer thread before redirects */
rb_execarg_parent_start(execarg_obj); rb_execarg_parent_start(execarg_obj);
fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name; fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;