From 1f226f1efeeae3a5091c60e2f51e027d0598f394 Mon Sep 17 00:00:00 2001 From: nagachika Date: Sun, 18 May 2025 13:32:52 +0900 Subject: [PATCH] merge revision(s) b959263b58e26ef630c085f9f7ddc04373a998c7: [Backport #21344] Fix Exception#detailed_message for GC compaction Before this commit, the test fails with RGENGC_CHECK_MODE enabled: TestException#test_detailed_message_under_gc_compact_stress [test/ruby/test_exception.rb:1466]: <"\e[1mfoo (\e[1;4mRuntimeError\e[m\e[1m)\e[m\n" + "\e[1mbar\e[m\n" + "\e[1mbaz\e[m"> expected but was <"\e[1mfoo (\e[1;4mRuntimeError\e[m\e[1m)\e[m\n" + "\e[1m\x00\x00\x00\x00\x00\x00\x00\e[m">. --- error.c | 2 +- eval_error.c | 4 +++- test/ruby/test_exception.rb | 8 ++++++++ version.h | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/error.c b/error.c index 9340bf5673..32409e1e41 100644 --- a/error.c +++ b/error.c @@ -1662,7 +1662,7 @@ exc_detailed_message(int argc, VALUE *argv, VALUE exc) VALUE highlight = check_highlight_keyword(opt, 0); - extern VALUE rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight); + extern VALUE rb_decorate_message(const VALUE eclass, VALUE emesg, int highlight); return rb_decorate_message(CLASS_OF(exc), rb_get_message(exc), RTEST(highlight)); } diff --git a/eval_error.c b/eval_error.c index bdce295f6e..d58df5a737 100644 --- a/eval_error.c +++ b/eval_error.c @@ -125,7 +125,7 @@ print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg, const VA } VALUE -rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight) +rb_decorate_message(const VALUE eclass, VALUE emesg, int highlight) { const char *einfo = ""; long elen = 0; @@ -210,6 +210,8 @@ rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight) } } + RB_GC_GUARD(emesg); + return str; } diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb index 07b39d1217..b3951c7e51 100644 --- a/test/ruby/test_exception.rb +++ b/test/ruby/test_exception.rb @@ -1459,6 +1459,14 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status| assert_equal("\e[1mRuntimeError (\e[1;4mRuntimeError\e[m\e[1m)\e[m", e.detailed_message(highlight: true)) end + def test_detailed_message_under_gc_compact_stress + EnvUtil.under_gc_compact_stress do + e = RuntimeError.new("foo\nbar\nbaz") + assert_equal("foo (RuntimeError)\nbar\nbaz", e.detailed_message) + assert_equal("\e[1mfoo (\e[1;4mRuntimeError\e[m\e[1m)\e[m\n\e[1mbar\e[m\n\e[1mbaz\e[m", e.detailed_message(highlight: true)) + end + end + def test_full_message_with_custom_detailed_message e = RuntimeError.new("message") opt_ = nil diff --git a/version.h b/version.h index a3e2371761..ee70d4de22 100644 --- a/version.h +++ b/version.h @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 8 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 151 +#define RUBY_PATCHLEVEL 152 #include "ruby/version.h" #include "ruby/internal/abi.h"