Merge branch 'alexischr/nursery-canaries-managed-alloc'
authorAlexis Christoforides <alexis@thenull.net>
Tue, 22 Nov 2016 19:10:22 +0000 (14:10 -0500)
committerAlexis Christoforides <alexis@thenull.net>
Tue, 22 Nov 2016 19:12:53 +0000 (14:12 -0500)
mono/metadata/sgen-mono.c
mono/sgen/sgen-gc.h

index 26e6a089b5dbb987e5d5cb6af8efc54b7c63eca1..6930b8e3f5e91caefd0ea61d76127238595da906 100644 (file)
@@ -1066,7 +1066,7 @@ static gboolean use_managed_allocator = TRUE;
 static MonoMethod*
 create_allocator (int atype, ManagedAllocatorVariant variant)
 {
-       int p_var, size_var, thread_var G_GNUC_UNUSED;
+       int p_var, size_var, real_size_var, thread_var G_GNUC_UNUSED;
        gboolean slowpath = variant == MANAGED_ALLOCATOR_SLOW_PATH;
        guint32 slowpath_branch, max_size_branch;
        MonoMethodBuilder *mb;
@@ -1279,6 +1279,14 @@ create_allocator (int atype, ManagedAllocatorVariant variant)
        mono_mb_emit_i4 (mb, MONO_MEMORY_BARRIER_NONE);
 #endif
 
+       if (nursery_canaries_enabled ()) {
+               real_size_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+               mono_mb_emit_ldloc (mb, size_var);
+               mono_mb_emit_stloc(mb, real_size_var);
+       }
+       else
+               real_size_var = size_var;
+
        /* size += ALLOC_ALIGN - 1; */
        mono_mb_emit_ldloc (mb, size_var);
        mono_mb_emit_icon (mb, SGEN_ALLOC_ALIGN - 1);
@@ -1317,6 +1325,11 @@ create_allocator (int atype, ManagedAllocatorVariant variant)
        mono_mb_emit_ldloc (mb, size_var);
        mono_mb_emit_byte (mb, CEE_CONV_I);
        mono_mb_emit_byte (mb, CEE_ADD);
+
+       if (nursery_canaries_enabled ()) {
+                       mono_mb_emit_icon (mb, CANARY_SIZE);
+                       mono_mb_emit_byte (mb, CEE_ADD);
+       }
        mono_mb_emit_stloc (mb, new_next_var);
 
        /* if (G_LIKELY (new_next < tlab_temp_end)) */
@@ -1345,7 +1358,7 @@ create_allocator (int atype, ManagedAllocatorVariant variant)
 
        /* FIXME: mono_gc_alloc_obj takes a 'size_t' as an argument, not an int32 */
        mono_mb_emit_ldarg (mb, 0);
-       mono_mb_emit_ldloc (mb, size_var);
+       mono_mb_emit_ldloc (mb, real_size_var);
        if (atype == ATYPE_NORMAL || atype == ATYPE_SMALL) {
                mono_mb_emit_icall (mb, mono_gc_alloc_obj);
        } else if (atype == ATYPE_VECTOR) {
@@ -1374,6 +1387,17 @@ create_allocator (int atype, ManagedAllocatorVariant variant)
        mono_mb_emit_ldarg (mb, 0);
        mono_mb_emit_byte (mb, CEE_STIND_I);
 
+       /* mark object end with nursery word */
+       if (nursery_canaries_enabled ()) {
+                       mono_mb_emit_ldloc (mb, p_var);
+                       mono_mb_emit_ldloc (mb, real_size_var);
+                       mono_mb_emit_byte (mb, MONO_CEE_ADD);
+                       mono_mb_emit_icon8 (mb, (mword) CANARY_STRING);
+                       mono_mb_emit_icon (mb, CANARY_SIZE);
+                       mono_mb_emit_byte (mb, MONO_CEE_PREFIX1);
+                       mono_mb_emit_byte (mb, CEE_CPBLK);
+       }
+
        if (atype == ATYPE_VECTOR) {
                /* arr->max_length = max_length; */
                mono_mb_emit_ldloc (mb, p_var);
@@ -3010,9 +3034,6 @@ mono_gc_base_init (void)
 
        sgen_gc_init ();
 
-       if (nursery_canaries_enabled ())
-               sgen_set_use_managed_allocator (FALSE);
-
 #if defined(HAVE_KW_THREAD)
        /* This can happen with using libmonosgen.so */
        if (mono_tls_key_get_offset (TLS_KEY_SGEN_THREAD_INFO) == -1)
index a767781ac56752a11bb304aa7edd4a3e0d7b6601..e5bcfcf134f394421685961aaf75679c678802eb 100644 (file)
@@ -1058,15 +1058,30 @@ gboolean nursery_canaries_enabled (void);
 #define CANARY_VALID(addr) (strncmp ((char*) (addr), CANARY_STRING, CANARY_SIZE) == 0)
 
 #define CHECK_CANARY_FOR_OBJECT(addr,fail) if (nursery_canaries_enabled ()) {  \
-                               char* canary_ptr = (char*) (addr) + sgen_safe_object_get_size_unaligned ((GCObject *) (addr));  \
+                               guint size = sgen_safe_object_get_size_unaligned ((GCObject *) (addr)); \
+                               char* canary_ptr = (char*) (addr) + size;       \
                                if (!CANARY_VALID(canary_ptr)) {        \
-                                       char canary_copy[CANARY_SIZE +1];       \
-                                       strncpy (canary_copy, canary_ptr, CANARY_SIZE); \
-                                       canary_copy[CANARY_SIZE] = 0;   \
-                                       if ((fail))                     \
-                                               g_error ("CORRUPT CANARY:\naddr->%p\ntype->%s\nexcepted->'%s'\nfound->'%s'\n", (char*) addr, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE ((addr))), CANARY_STRING, canary_copy); \
-                                       else                            \
-                                               g_warning ("CORRUPT CANARY:\naddr->%p\ntype->%s\nexcepted->'%s'\nfound->'%s'\n", (char*) addr, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE ((addr))), CANARY_STRING, canary_copy); \
+                                       char *window_start, *window_end; \
+                                       window_start = (char*)(addr) - 128; \
+                                       if (!sgen_ptr_in_nursery (window_start)) \
+                                               window_start = sgen_get_nursery_start (); \
+                                       window_end = (char*)(addr) + 128; \
+                                       if (!sgen_ptr_in_nursery (window_end)) \
+                                               window_end = sgen_get_nursery_end (); \
+                                       fprintf (stderr, "\nCANARY ERROR - Type:%s Size:%d Address:%p Data:\n", sgen_client_vtable_get_name (SGEN_LOAD_VTABLE ((addr))), size,  (char*) addr); \
+                                       fwrite (addr, sizeof (char), size, stderr); \
+                                       fprintf (stderr, "\nCanary zone (next 12 chars):\n"); \
+                                       fwrite (canary_ptr, sizeof (char), 12, stderr); \
+                                       fprintf (stderr, "\nOriginal canary string:\n"); \
+                                       fwrite (CANARY_STRING, sizeof (char), 8, stderr); \
+                                       for (int x = -8; x <= 8; x++) { \
+                                               if (canary_ptr + x < (char*) addr); \
+                                                       continue; \
+                                               if (CANARY_VALID(canary_ptr +x)) \
+                                                       fprintf (stderr, "\nCANARY ERROR - canary found at offset %d\n", x); \
+                                       } \
+                                       fprintf (stderr, "\nSurrounding nursery (%p - %p):\n", window_start, window_end); \
+                                       fwrite (window_start, sizeof (char), window_end - window_start, stderr); \
                                } }
 
 /*