Skip to content

Commit

Permalink
Fix Exception#detailed_message for GC compaction
Browse files Browse the repository at this point in the history
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">.
  • Loading branch information
peterzhu2118 committed Jan 2, 2024
1 parent 28ec794 commit b959263
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 2 deletions.
2 changes: 1 addition & 1 deletion error.c
Expand Up @@ -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));
}
Expand Down
4 changes: 3 additions & 1 deletion eval_error.c
Expand Up @@ -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;
Expand Down Expand Up @@ -210,6 +210,8 @@ rb_decorate_message(const VALUE eclass, const VALUE emesg, int highlight)
}
}

RB_GC_GUARD(emesg);

return str;
}

Expand Down
8 changes: 8 additions & 0 deletions test/ruby/test_exception.rb
Expand Up @@ -1459,6 +1459,14 @@ def test_detailed_message
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
Expand Down

0 comments on commit b959263

Please sign in to comment.