fix for 2 crashes freeing masks
authorCampbell Barton <ideasman42@gmail.com>
Fri, 14 Sep 2012 01:15:08 +0000 (01:15 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 14 Sep 2012 01:15:08 +0000 (01:15 +0000)
- freeing a mask from RNA BKE_libblock_free() twice on the mask.
- loading a new blend file would only free the mask and not unlink it from nodes - it would access freed memory.

source/blender/blenkernel/BKE_mask.h
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/mask.c
source/blender/blenkernel/intern/sequencer.c
source/blender/compositor/operations/COM_MaskOperation.cpp
source/blender/makesrna/intern/rna_main_api.c

index 9ce678d8988fa292bcc680b27f9f6aa052ba45e5..51e301fec80a9c08f012925637111ebb0e738268 100644 (file)
@@ -102,8 +102,8 @@ struct Mask *BKE_mask_new(const char *name);
 struct Mask *BKE_mask_copy_nolib(struct Mask *mask);
 struct Mask *BKE_mask_copy(struct Mask *mask);
 
-void BKE_mask_free(struct Mask *mask);
-void BKE_mask_unlink(struct Main *bmain, struct Mask *mask);
+void BKE_mask_free_nolib(struct Mask *mask);
+void BKE_mask_free(struct Main *bmain, struct Mask *mask);
 
 void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2]);
 void BKE_mask_coord_from_movieclip(struct MovieClip *clip, struct MovieClipUser *user, float r_co[2], const float co[2]);
index f8c1a35776a1894bcbd84b22e59a0aad4510bfd6..45364f5aafa85081830c16b1f75740cd74e6dd19 100644 (file)
@@ -800,6 +800,7 @@ static void animdata_dtar_clear_cb(ID *UNUSED(id), AnimData *adt, void *userdata
 /* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c */
 void BKE_libblock_free(ListBase *lb, void *idv)
 {
+       Main *bmain = G.main;  /* should eventually be an arg */
        ID *id = idv;
 
 #ifdef WITH_PYTHON
@@ -899,7 +900,7 @@ void BKE_libblock_free(ListBase *lb, void *idv)
                        BKE_movieclip_free((MovieClip *)id);
                        break;
                case ID_MSK:
-                       BKE_mask_free((Mask *)id);
+                       BKE_mask_free(bmain, (Mask *)id);
                        break;
        }
 
@@ -911,7 +912,7 @@ void BKE_libblock_free(ListBase *lb, void *idv)
        BLI_remlink(lb, id);
 
        /* this ID may be a driver target! */
-       BKE_animdata_main_cb(G.main, animdata_dtar_clear_cb, (void *)id);
+       BKE_animdata_main_cb(bmain, animdata_dtar_clear_cb, (void *)id);
 
        MEM_freeN(id);
 }
@@ -946,9 +947,52 @@ void free_main(Main *mainvar)
                ID *id;
                
                while ( (id = lb->first) ) {
+#if 1
                        BKE_libblock_free(lb, id);
+#else
+                       /* errors freeing ID's can be hard to track down,
+                        * enable this so valgrind will give the line number in its error log */
+                       switch (a) {
+                               case   0: BKE_libblock_free(lb, id); break;
+                               case   1: BKE_libblock_free(lb, id); break;
+                               case   2: BKE_libblock_free(lb, id); break;
+                               case   3: BKE_libblock_free(lb, id); break;
+                               case   4: BKE_libblock_free(lb, id); break;
+                               case   5: BKE_libblock_free(lb, id); break;
+                               case   6: BKE_libblock_free(lb, id); break;
+                               case   7: BKE_libblock_free(lb, id); break;
+                               case   8: BKE_libblock_free(lb, id); break;
+                               case   9: BKE_libblock_free(lb, id); break;
+                               case  10: BKE_libblock_free(lb, id); break;
+                               case  11: BKE_libblock_free(lb, id); break;
+                               case  12: BKE_libblock_free(lb, id); break;
+                               case  13: BKE_libblock_free(lb, id); break;
+                               case  14: BKE_libblock_free(lb, id); break;
+                               case  15: BKE_libblock_free(lb, id); break;
+                               case  16: BKE_libblock_free(lb, id); break;
+                               case  17: BKE_libblock_free(lb, id); break;
+                               case  18: BKE_libblock_free(lb, id); break;
+                               case  19: BKE_libblock_free(lb, id); break;
+                               case  20: BKE_libblock_free(lb, id); break;
+                               case  21: BKE_libblock_free(lb, id); break;
+                               case  22: BKE_libblock_free(lb, id); break;
+                               case  23: BKE_libblock_free(lb, id); break;
+                               case  24: BKE_libblock_free(lb, id); break;
+                               case  25: BKE_libblock_free(lb, id); break;
+                               case  26: BKE_libblock_free(lb, id); break;
+                               case  27: BKE_libblock_free(lb, id); break;
+                               case  28: BKE_libblock_free(lb, id); break;
+                               case  29: BKE_libblock_free(lb, id); break;
+                               case  30: BKE_libblock_free(lb, id); break;
+                               case  31: BKE_libblock_free(lb, id); break;
+                               case  32: BKE_libblock_free(lb, id); break;
+                               default:
+                                       BLI_assert(0);
+                       }
+#endif
                }
        }
+       a = set_listbasepointers(mainvar, lbarray);
 
        MEM_freeN(mainvar);
 }
index 06d063574a5fb866a67924e485e87b5f7c33716d..97b46d4829d9d68f415bbdb0ce5ca8f2a348a3cf 100644 (file)
@@ -910,7 +910,8 @@ void BKE_mask_layer_free_list(ListBase *masklayers)
        }
 }
 
-void BKE_mask_free(Mask *mask)
+/** free for temp copy, but don't manage unlinking from other pointers */
+void BKE_mask_free_nolib(Mask *mask)
 {
        BKE_mask_layer_free_list(&mask->masklayers);
 }
@@ -928,7 +929,7 @@ static void ntree_unlink_mask_cb(void *calldata, struct ID *UNUSED(owner_id), st
        }
 }
 
-void BKE_mask_unlink(Main *bmain, Mask *mask)
+void BKE_mask_free(Main *bmain, Mask *mask)
 {
        bScreen *scr;
        ScrArea *area;
@@ -991,7 +992,8 @@ void BKE_mask_unlink(Main *bmain, Mask *mask)
                treetype->foreach_nodetree(bmain, (void *)mask, &ntree_unlink_mask_cb);
        }
 
-       BKE_libblock_free(&bmain->mask, mask);
+       /* free mask data */
+       BKE_mask_layer_free_list(&mask->masklayers);
 }
 
 void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2])
index b191b25be625d7a520a1629b8f44dc9ddfe99ea6..07c8da2837e5d5fa07a728e3fe9bb7e808976270 100644 (file)
@@ -2157,7 +2157,7 @@ static ImBuf *seq_render_mask(SeqRenderData context, Mask *mask, float nr, short
 
                BKE_maskrasterize_handle_init(mr_handle, mask_temp, context.rectx, context.recty, TRUE, TRUE, TRUE);
 
-               BKE_mask_free(mask_temp);
+               BKE_mask_free_nolib(mask_temp);
                MEM_freeN(mask_temp);
 
                BKE_maskrasterize_buffer(mr_handle, context.rectx, context.recty, maskbuf);
index a156dfc1d99d57c7c12f0a280c55420b62c23ef8..36b3f2023ae564325c4e68ac5d3cd7be4ef25cb1 100644 (file)
@@ -93,7 +93,7 @@ void MaskOperation::initExecution()
                                frame_iter += frame_step;
                        }
 
-                       BKE_mask_free(mask_temp);
+                       BKE_mask_free_nolib(mask_temp);
                        MEM_freeN(mask_temp);
                }
        }
index 8a2374060cf77e7a437bcfeef470654bbcd24892..307982e4bb13db927e599da8aca1fc45ecf12541 100644 (file)
@@ -556,7 +556,7 @@ Mask *rna_Main_mask_new(Main *UNUSED(bmain), const char *name)
 
 void rna_Main_masks_remove(Main *bmain, Mask *mask)
 {
-       BKE_mask_unlink(bmain, mask);
+       BKE_mask_free(bmain, mask);
        BKE_libblock_free(&bmain->mask, mask);
        /* XXX python now has invalid pointer? */
 }