summaryrefslogtreecommitdiff
path: root/timev.h
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 /timev.h
parent06da0d1456f52a69ad19a0a8cc35e3359d2d144c (diff)
downloadruby-a84c99468f26a9f79fec57926d561ed906505eac.tar.gz
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
Diffstat (limited to 'timev.h')
-rw-r--r--timev.h7
1 files changed, 5 insertions, 2 deletions
diff --git a/timev.h b/timev.h
index d667b60b14..d350a170de 100644
--- a/timev.h
+++ b/timev.h
@@ -2,7 +2,6 @@
#define RUBY_TIMEV_H
#include "ruby/ruby.h"
-RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_BEGIN()
struct vtm {
VALUE year; /* 2000 for example. Integer. */
VALUE subsecx; /* 0 <= subsecx < TIME_SCALE. possibly Rational. */
@@ -16,7 +15,11 @@ struct vtm {
unsigned int sec:6; /* 0..60 */
unsigned int wday:3; /* 0:Sunday, 1:Monday, ..., 6:Saturday 7:init */
unsigned int isdst:2; /* 0:StandardTime 1:DayLightSavingTime 3:init */
-} RBIMPL_ATTR_PACKED_STRUCT_UNALIGNED_END();
+
+ /* Flags for struct time_object */
+ unsigned int tzmode:3; /* 0:localtime 1:utc 2:fixoff 3:uninitialized */
+ unsigned int tm_got:1;
+};
#define TIME_SCALE 1000000000