From 369cfabd5936ccb522f8e95e0f9cc65b59ea4039 Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Sat, 5 Sep 2020 21:18:45 +0900 Subject: Make it possible to dump and load an exception object A backtrace object in an exception had never supported marshalling correctly: `Marshal.load(Marshal.dump(exc)).backtrace_locations` dumped core. An Exception object has two hidden instance varibles for backtrace data: one is "bt", which has an Array of Strings, and the other is "bt_locations", which has an Array of Thread::Backtrace::Locations. However, Exception's dump outputs data so that the two variables are the same Array of Strings. Thus, "bt_locations" had a wrong-type object. For the compatibility, it is difficult to change the dump format. This changeset fixes the issue by ignoring data for "bt_locations" at the loading phase if "bt_locations" refers to the same object as "bt". Future work: Exception's dump should output "bt_locations" appropriately. https://bugs.ruby-lang.org/issues/17150 --- test/ruby/test_marshal.rb | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'test') diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb index 1d096adb18..fd62ea774b 100644 --- a/test/ruby/test_marshal.rb +++ b/test/ruby/test_marshal.rb @@ -780,4 +780,35 @@ class TestMarshal < Test::Unit::TestCase hash = Marshal.load(Marshal.dump(flagged_hash)) assert_equal(42, ruby2_keywords_test(*[hash])) end + + def exception_test + raise + end + + def test_marshal_exception + begin + exception_test + rescue => e + e2 = Marshal.load(Marshal.dump(e)) + assert_equal(e.message, e2.message) + assert_equal(e.backtrace, e2.backtrace) + assert_nil(e2.backtrace_locations) # temporal + end + end + + def nameerror_test + unknown_method + end + + def test_marshal_nameerror + begin + nameerror_test + rescue NameError => e + e2 = Marshal.load(Marshal.dump(e)) + assert_equal(e.message, e2.message) + assert_equal(e.name, e2.name) + assert_equal(e.backtrace, e2.backtrace) + assert_nil(e2.backtrace_locations) # temporal + end + end end -- cgit v1.2.3