Skip to content
  • Peter Zhu's avatar
    a84c9946
    Fix crash in Time on 32-bit systems · a84c9946
    Peter Zhu authored
    [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
    a84c9946
    Fix crash in Time on 32-bit systems
    Peter Zhu authored
    [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
Loading