From 686589207c22f6e52e0772121e66dc89b6087173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Sat, 21 Mar 2015 12:26:23 +0100 Subject: [PATCH] ruby: fix crash on /plugin reload (closes #364) The call to ruby_init_loadpath() has been moved after ruby initializations, which fixes the crash on plugin reload. The errors during ruby initializations are now displayed (they were hidden). And the ruby_cleanup() is called again: it seems it does not crash any more (tested with Ruby 2.1.5). --- ChangeLog.asciidoc | 1 + src/plugins/ruby/weechat-ruby.c | 51 +++++++++++++++------------------ 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/ChangeLog.asciidoc b/ChangeLog.asciidoc index 76ef366de..8a8f7e5b6 100644 --- a/ChangeLog.asciidoc +++ b/ChangeLog.asciidoc @@ -61,6 +61,7 @@ https://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes] * python: fix name of function "bar_update" in case of error * python: fix restore of old interpreter when a function is not found in the script +* ruby: fix crash on /plugin reload (closes #364) * ruby: fix value returned in case of error in functions: config_option_reset, config_color, config_color_default, config_write, config_read, config_reload, buffer_string_replace_local_var, command diff --git a/src/plugins/ruby/weechat-ruby.c b/src/plugins/ruby/weechat-ruby.c index d5cb4684a..1e55a23bb 100644 --- a/src/plugins/ruby/weechat-ruby.c +++ b/src/plugins/ruby/weechat-ruby.c @@ -436,14 +436,14 @@ weechat_ruby_exec (struct t_plugin_script *script, static VALUE weechat_ruby_output (VALUE self, VALUE str) { - if (ruby_hide_errors) - return Qnil; - char *msg, *p, *m; /* make C compiler happy */ (void) self; + if (ruby_hide_errors) + return Qnil; + msg = strdup(StringValuePtr(str)); m = msg; @@ -1153,38 +1153,38 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) RUBY_INIT_STACK; #endif - ruby_hide_errors = 1; ruby_init (); - ruby_init_loadpath (); - ruby_script ("__weechat_plugin__"); - - ruby_mWeechat = rb_define_module("Weechat"); - weechat_ruby_api_init (ruby_mWeechat); /* redirect stdin and stdout */ - ruby_mWeechatOutputs = rb_define_module("WeechatOutputs"); - rb_define_singleton_method(ruby_mWeechatOutputs, "write", - weechat_ruby_output, 1); - rb_define_singleton_method(ruby_mWeechatOutputs, "puts", - weechat_ruby_output, 1); - rb_define_singleton_method(ruby_mWeechatOutputs, "p", - weechat_ruby_output, 1); - rb_define_singleton_method(ruby_mWeechatOutputs, "flush", - weechat_ruby_output_flush, 0); - ruby_hide_errors = 0; + ruby_mWeechatOutputs = rb_define_module ("WeechatOutputs"); + rb_define_singleton_method (ruby_mWeechatOutputs, "write", + weechat_ruby_output, 1); + rb_define_singleton_method (ruby_mWeechatOutputs, "puts", + weechat_ruby_output, 1); + rb_define_singleton_method (ruby_mWeechatOutputs, "p", + weechat_ruby_output, 1); + rb_define_singleton_method (ruby_mWeechatOutputs, "flush", + weechat_ruby_output_flush, 0); - rb_eval_string_protect(weechat_ruby_code, &ruby_error); + ruby_script ("__weechat_plugin__"); + + ruby_mWeechat = rb_define_module ("Weechat"); + weechat_ruby_api_init (ruby_mWeechat); + + rb_eval_string_protect (weechat_ruby_code, &ruby_error); if (ruby_error) { weechat_printf (NULL, weechat_gettext ("%s%s: unable to eval WeeChat ruby " "internal code"), weechat_prefix ("error"), RUBY_PLUGIN_NAME); - VALUE err = rb_gv_get("$!"); - weechat_ruby_print_exception(err); + VALUE err = rb_gv_get ("$!"); + weechat_ruby_print_exception (err); return WEECHAT_RC_ERROR; } + ruby_init_loadpath (); + init.callback_command = &weechat_ruby_command_cb; init.callback_completion = &weechat_ruby_completion_cb; init.callback_hdata = &weechat_ruby_hdata_cb; @@ -1218,12 +1218,7 @@ weechat_plugin_end (struct t_weechat_plugin *plugin) plugin_script_end (plugin, &ruby_scripts, &weechat_ruby_unload_all); ruby_quiet = 0; - /* - * Do not cleanup ruby because this causes a crash when plugin is reloaded - * again. This causes a memory leak, but I don't know better solution to - * this problem :( - */ - /*ruby_cleanup (0);*/ + ruby_cleanup (0); /* free some data */ if (ruby_action_install_list)