[coop] Make sure 'gc_stackdata' is aligned and properly sized.
authorAlexis Christoforides <alexis@thenull.net>
Tue, 3 Nov 2015 14:06:14 +0000 (09:06 -0500)
committerAlexis Christoforides <alexis@thenull.net>
Tue, 3 Nov 2015 15:30:04 +0000 (10:30 -0500)
The size of the gc_stackdata buffer was not a multiple of 8 bytes on 64-bits, so sgen_conservatively_pin_objects_from () would address invalid memory on its last iteration, as it progresses down the buffer by pointer size. The function also expects memory references to be aligned.

This is still not a guarantee that we are aligning memory references properly as two misaligns will still give the right size, but we can catch some of them here. Proper sizing is a smaller issue because we could always pad.

mono/utils/mono-threads-coop.c

index 03e0aba0bb160e2afbbb4847d79f044076cb9823..edfb11d6c028b7aea1737d98cfa8d0c13173af19 100644 (file)
@@ -83,7 +83,7 @@ mono_threads_state_poll (void)
 static void *
 return_stack_ptr ()
 {
-       int i;
+       gpointer i;
        return &i;
 }
 
@@ -99,6 +99,12 @@ copy_stack_data (MonoThreadInfo *info, void* stackdata_begin)
        state = &info->thread_saved_state [SELF_SUSPEND_STATE_INDEX];
 
        stackdata_size = (char*)stackdata_begin - (char*)stackdata_end;
+
+       if (((gsize) stackdata_begin & (SIZEOF_VOID_P - 1)) != 0)
+               g_error ("stackdata_begin (%p) must be %d-byte aligned", stackdata_begin, SIZEOF_VOID_P);
+       if (((gsize) stackdata_end & (SIZEOF_VOID_P - 1)) != 0)
+               g_error ("stackdata_end (%p) must be %d-byte aligned", stackdata_end, SIZEOF_VOID_P);
+
        if (stackdata_size <= 0)
                g_error ("stackdata_size = %d, but must be > 0, stackdata_begin = %p, stackdata_end = %p", stackdata_size, stackdata_begin, stackdata_end);