summaryrefslogtreecommitdiff
path: root/test/ruby/test_time.rb
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2023-04-04 09:27:45 -0400
committerPeter Zhu <peter@peterzhu.ca>2023-04-04 11:12:07 -0400
commita84c99468f26a9f79fec57926d561ed906505eac (patch)
tree86c94feef11c4682f4330ed67dc3bc2be15a09d5 /test/ruby/test_time.rb
parent06da0d1456f52a69ad19a0a8cc35e3359d2d144c (diff)
Fix crash in Time on 32-bit systems
[Bug #19575] struct vtm is packed causing it to have a size that is not aligned on 32-bit systems. When allocating it on the stack, it will have unaligned addresses which means that the fields won't be marked by the GC when scanning the stack (since the GC only marks aligned addresses). This can cause crashes when the fields are heap allocated objects like Bignums. This commit moves the flags in struct time_object into struct vtm for space efficiency and removes the need for packing. This is an example of a crash: ruby(rb_print_backtrace+0xd) [0x56848945] ../src/vm_dump.c:785 ruby(rb_vm_bugreport) ../src/vm_dump.c:1101 ruby(rb_assert_failure+0x7a) [0x56671857] ../src/error.c:878 ruby(vm_search_cc+0x0) [0x56666e47] ../src/vm_method.c:1366 ruby(rb_vm_search_method_slowpath) ../src/vm_insnhelper.c:2090 ruby(callable_method_entry+0x5) [0x568232d3] ../src/vm_method.c:1406 ruby(rb_callable_method_entry) ../src/vm_method.c:1413 ruby(gccct_method_search_slowpath) ../src/vm_eval.c:427 ruby(gccct_method_search+0x20f) [0x568237ef] ../src/vm_eval.c:476 ruby(opt_equality_by_mid_slowpath+0x2c) [0x5682388c] ../src/vm_insnhelper.c:2338 ruby(rb_equal+0x37) [0x566fe577] ../src/object.c:133 ruby(rb_big_eq+0x34) [0x56876ee4] ../src/bignum.c:5554 ruby(rb_int_equal+0x14) [0x566f3ed4] ../src/numeric.c:4640 ruby(rb_int_equal) ../src/numeric.c:4634 ruby(vm_call0_cfunc_with_frame+0x6d) [0x568303c2] ../src/vm_eval.c:148 ruby(vm_call0_cfunc) ../src/vm_eval.c:162 ruby(vm_call0_body) ../src/vm_eval.c:208 ruby(rb_funcallv_scope+0xd1) [0x56833971] ../src/vm_eval.c:85 ruby(RB_TEST+0x0) [0x567e8488] ../src/time.c:78 ruby(eq) ../src/time.c:78 ruby(small_vtm_sub) ../src/time.c:1523 ruby(timelocalw+0x23b) [0x567f3e9b] ../src/time.c:1593 ruby(time_s_alloc+0x0) [0x567f536b] ../src/time.c:3698 ruby(time_new_timew) ../src/time.c:2694 ruby(time_s_mktime) ../src/time.c:3698
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7650
Diffstat (limited to 'test/ruby/test_time.rb')
-rw-r--r--test/ruby/test_time.rb7
1 files changed, 2 insertions, 5 deletions
diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb
index 2bf6056a49..f47a49d3e0 100644
--- a/test/ruby/test_time.rb
+++ b/test/ruby/test_time.rb
@@ -1403,11 +1403,8 @@ class TestTime < Test::Unit::TestCase
else
RbConfig::SIZEOF["void*"] # Same size as VALUE
end
- expect =
- GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] +
- sizeof_timew +
- RbConfig::SIZEOF["void*"] * 4 + 5 + # vtm
- 1 # tzmode, tm_got
+ sizeof_vtm = RbConfig::SIZEOF["void*"] * 4 + 8
+ expect = GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] + sizeof_timew + sizeof_vtm
assert_equal expect, ObjectSpace.memsize_of(t)
rescue LoadError => e
omit "failed to load objspace: #{e.message}"