ruby-changes:50320
From: nagachika <ko1@a...>
Date: Sat, 17 Feb 2018 00:27:43 +0900 (JST)
Subject: [ruby-changes:50320] nagachika:r62435 (ruby_2_4): merge revision(s) 58471, 58493: [Backport #13505]
nagachika 2018-02-17 00:27:37 +0900 (Sat, 17 Feb 2018) New Revision: 62435 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62435 Log: merge revision(s) 58471,58493: [Backport #13505] load.c: backtrace of circular require * load.c (load_lock): print backtrace of circular require via `Warning.warn` [ruby-core:80850] [Bug #13505] Send the backtrace of the circular require warning as a single String to Warning.warn * load.c: send as a single string. * error.c: expose the string formatted by rb_warning as rb_warning_string(). * test/ruby/test_exception.rb: update tests. [ruby-core:80850] [Bug #13505] Modified directories: branches/ruby_2_4/ Modified files: branches/ruby_2_4/error.c branches/ruby_2_4/internal.h branches/ruby_2_4/load.c branches/ruby_2_4/test/ruby/test_exception.rb branches/ruby_2_4/version.h branches/ruby_2_4/vm_backtrace.c Index: ruby_2_4/test/ruby/test_exception.rb =================================================================== --- ruby_2_4/test/ruby/test_exception.rb (revision 62434) +++ ruby_2_4/test/ruby/test_exception.rb (revision 62435) @@ -934,23 +934,23 @@ $stderr = $stdout; raise "\x82\xa0"') do https://github.com/ruby/ruby/blob/trunk/ruby_2_4/test/ruby/test_exception.rb#L934 end end - def test_warning_warn + def capture_warning_warn verbose = $VERBOSE - warning = nil + warning = [] ::Warning.class_eval do alias_method :warn2, :warn remove_method :warn define_method(:warn) do |str| - warning = str + warning << str end end $VERBOSE = true - a = @a + yield - assert_match(/instance variable @a not initialized/, warning) + return warning ensure $VERBOSE = verbose @@ -961,6 +961,11 @@ $stderr = $stdout; raise "\x82\xa0"') do https://github.com/ruby/ruby/blob/trunk/ruby_2_4/test/ruby/test_exception.rb#L961 end end + def test_warning_warn + warning = capture_warning_warn {@a} + assert_match(/instance variable @a not initialized/, warning[0]) + end + def test_warning_warn_invalid_argument assert_raise(TypeError) do ::Warning.warn nil @@ -973,6 +978,27 @@ $stderr = $stdout; raise "\x82\xa0"') do https://github.com/ruby/ruby/blob/trunk/ruby_2_4/test/ruby/test_exception.rb#L978 end end + def test_warning_warn_circular_require_backtrace + warning = nil + path = nil + Tempfile.create(%w[circular .rb]) do |t| + begin + path = t.path + basename = File.basename(path) + t.puts "require '#{basename}'" + t.close + $LOAD_PATH.push(File.dirname(t)) + warning = capture_warning_warn {require basename} + ensure + $LOAD_PATH.pop + $LOADED_FEATURES.delete(t) + end + end + assert_equal(1, warning.size) + assert_match(/circular require/, warning.first) + assert_match(/^\tfrom #{Regexp.escape(path)}:1:/, warning.first) + end + def test_undefined_backtrace assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}") begin; Index: ruby_2_4/error.c =================================================================== --- ruby_2_4/error.c (revision 62434) +++ ruby_2_4/error.c (revision 62435) @@ -162,10 +162,16 @@ rb_warning_s_warn(VALUE mod, VALUE str) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/error.c#L162 return Qnil; } +VALUE +rb_warning_warn(VALUE mod, VALUE str) +{ + return rb_funcallv(mod, id_warn, 1, &str); +} + static void rb_write_warning_str(VALUE str) { - rb_funcall(rb_mWarning, id_warn, 1, str); + rb_warning_warn(rb_mWarning, str); } static VALUE @@ -254,6 +260,14 @@ rb_warning(const char *fmt, ...) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/error.c#L260 } } +VALUE +rb_warning_string(const char *fmt, ...) +{ + with_warning_string(mesg, 0, fmt) { + } + return mesg; +} + #if 0 void rb_enc_warning(rb_encoding *enc, const char *fmt, ...) Index: ruby_2_4/version.h =================================================================== --- ruby_2_4/version.h (revision 62434) +++ ruby_2_4/version.h (revision 62435) @@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/version.h#L1 #define RUBY_VERSION "2.4.4" -#define RUBY_RELEASE_DATE "2018-02-16" -#define RUBY_PATCHLEVEL 236 +#define RUBY_RELEASE_DATE "2018-02-17" +#define RUBY_PATCHLEVEL 237 #define RUBY_RELEASE_YEAR 2018 #define RUBY_RELEASE_MONTH 2 -#define RUBY_RELEASE_DAY 16 +#define RUBY_RELEASE_DAY 17 #include "ruby/version.h" Index: ruby_2_4/internal.h =================================================================== --- ruby_2_4/internal.h (revision 62434) +++ ruby_2_4/internal.h (revision 62435) @@ -1033,6 +1033,8 @@ VALUE rb_name_err_new(VALUE mesg, VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_4/internal.h#L1033 rb_name_err_raise_str(rb_fstring_cstr(mesg), (recv), (name)) NORETURN(void ruby_only_for_internal_use(const char *)); #define ONLY_FOR_INTERNAL_USE(func) ruby_only_for_internal_use(func) +VALUE rb_warning_warn(VALUE mod, VALUE str); +VALUE rb_warning_string(const char *fmt, ...); /* eval.c */ VALUE rb_refinement_module_get_refined_class(VALUE module); @@ -1641,7 +1643,7 @@ void rb_backtrace_print_as_bugreport(voi https://github.com/ruby/ruby/blob/trunk/ruby_2_4/internal.h#L1643 int rb_backtrace_p(VALUE obj); VALUE rb_backtrace_to_str_ary(VALUE obj); VALUE rb_backtrace_to_location_ary(VALUE obj); -void rb_backtrace_print_to(VALUE output); +void rb_backtrace_each(VALUE (*iter)(VALUE recv, VALUE str), VALUE output); VALUE rb_vm_backtrace_object(void); RUBY_SYMBOL_EXPORT_BEGIN Index: ruby_2_4/load.c =================================================================== --- ruby_2_4/load.c (revision 62434) +++ ruby_2_4/load.c (revision 62435) @@ -720,6 +720,8 @@ rb_f_load(int argc, VALUE *argv) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/load.c#L720 return Qtrue; } +extern VALUE rb_mWarning; + static char * load_lock(const char *ftptr) { @@ -742,8 +744,9 @@ load_lock(const char *ftptr) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/load.c#L744 return (char *)""; } if (RTEST(ruby_verbose)) { - rb_warning("loading in progress, circular require considered harmful - %s", ftptr); - rb_backtrace_print_to(rb_stderr); + VALUE warning = rb_warning_string("loading in progress, circular require considered harmful - %s", ftptr); + rb_backtrace_each(rb_str_append, warning); + rb_warning_warn(rb_mWarning, warning); } switch (rb_thread_shield_wait((VALUE)data)) { case Qfalse: Index: ruby_2_4/vm_backtrace.c =================================================================== --- ruby_2_4/vm_backtrace.c (revision 62434) +++ ruby_2_4/vm_backtrace.c (revision 62435) @@ -778,10 +778,15 @@ rb_backtrace(void) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/vm_backtrace.c#L778 vm_backtrace_print(stderr); } +struct print_to_arg { + VALUE (*iter)(VALUE recv, VALUE str); + VALUE output; +}; + static void oldbt_print_to(void *data, VALUE file, int lineno, VALUE name) { - VALUE output = (VALUE)data; + const struct print_to_arg *arg = data; VALUE str = rb_sprintf("\tfrom %"PRIsVALUE":%d:in ", file, lineno); if (NIL_P(name)) { @@ -790,16 +795,19 @@ oldbt_print_to(void *data, VALUE file, i https://github.com/ruby/ruby/blob/trunk/ruby_2_4/vm_backtrace.c#L795 else { rb_str_catf(str, " `%"PRIsVALUE"'\n", name); } - rb_io_write(output, str); + (*arg->iter)(arg->output, str); } void -rb_backtrace_print_to(VALUE output) +rb_backtrace_each(VALUE (*iter)(VALUE recv, VALUE str), VALUE output) { struct oldbt_arg arg; + struct print_to_arg parg; + parg.iter = iter; + parg.output = output; arg.func = oldbt_print_to; - arg.data = (void *)output; + arg.data = &parg; backtrace_each(GET_THREAD(), oldbt_init, oldbt_iter_iseq, Index: ruby_2_4 =================================================================== --- ruby_2_4 (revision 62434) +++ ruby_2_4 (revision 62435) Property changes on: ruby_2_4 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /trunk:r58471,58493 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/