summaryrefslogtreecommitdiff
path: root/test/ruby/test_marshal.rb
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2020-09-05 21:18:45 +0900
committerYusuke Endoh <mame@ruby-lang.org>2020-09-06 13:57:41 +0900
commit369cfabd5936ccb522f8e95e0f9cc65b59ea4039 (patch)
tree81eea199cc4f0fa663d709056eebe1f4f1a139b5 /test/ruby/test_marshal.rb
parentc12b2703bc05f8c7eaaace49253f63a5e0f28273 (diff)
downloadruby-369cfabd5936ccb522f8e95e0f9cc65b59ea4039.tar.gz
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
Diffstat (limited to 'test/ruby/test_marshal.rb')
-rw-r--r--test/ruby/test_marshal.rb31
1 files changed, 31 insertions, 0 deletions
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