Revision: 58959
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58959
Author:   blendix
Date:     2013-08-06 05:35:54 +0000 (Tue, 06 Aug 2013)
Log Message:
-----------
Fix crash loading .blend files that have multiple outliners in a screen, saved
with recent outliner optimizations (revision 58855, 3 days ago), in any Blender
version before this commit. On current Blender it would give a double free
warning in the console.

The problem is that it creates a temporary TreeStore on file save. However if 
you
have multiple outliners this memory block would always be at the same memory
address making it no longer unique. That then meant old memory address lookups 
on
file read were failing. Solution now is to postpone freeing these temporary 
memory
blocks until the end so that they are at unique addresses.

Revision Links:
--------------
    
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58855

Modified Paths:
--------------
    trunk/blender/source/blender/blenloader/intern/writefile.c

Modified: trunk/blender/source/blender/blenloader/intern/writefile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/writefile.c  2013-08-06 
05:05:31 UTC (rev 58958)
+++ trunk/blender/source/blender/blenloader/intern/writefile.c  2013-08-06 
05:35:54 UTC (rev 58959)
@@ -2394,7 +2394,7 @@
        }
 }
 
-static void write_soops(WriteData *wd, SpaceOops *so)
+static void write_soops(WriteData *wd, SpaceOops *so, LinkNode **tmp_mem_list)
 {
        BLI_mempool *ts = so->treestore;
        
@@ -2402,18 +2402,35 @@
                int elems = BLI_mempool_count(ts);
                /* linearize mempool to array */
                TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, 
"TreeStoreElem") : NULL;
-               TreeStore ts_flat = {elems, elems, data};
-               
-               /* temporarily replace mempool-treestore by flat-treestore */
-               so->treestore = (BLI_mempool *)&ts_flat;
-               writestruct(wd, DATA, "SpaceOops", 1, so);
-               /* restore old treestore */
-               so->treestore = ts;
-               writestruct(wd, DATA, "TreeStore", 1, &ts_flat);
+
                if (data) {
+                       TreeStore *ts_flat = MEM_callocN(sizeof(TreeStore), 
"TreeStore");
+
+                       ts_flat->usedelem = elems;
+                       ts_flat->totelem = elems;
+                       ts_flat->data = data;
+                       
+                       /* temporarily replace mempool-treestore by 
flat-treestore */
+                       so->treestore = (BLI_mempool *)ts_flat;
+                       writestruct(wd, DATA, "SpaceOops", 1, so);
+
+                       writestruct(wd, DATA, "TreeStore", 1, ts_flat);
                        writestruct(wd, DATA, "TreeStoreElem", elems, data);
-                       MEM_freeN(data);
+
+                       /* we do not free the pointers immediately, because if 
we have multiple
+                        * outliners in a screen we might get the same address 
on the next
+                        * malloc, which makes the address no longer unique and 
so invalid for
+                        * lookups on file read, causing crashes or double 
frees */
+                       BLI_linklist_append(tmp_mem_list, ts_flat);
+                       BLI_linklist_append(tmp_mem_list, data);
                }
+               else {
+                       so->treestore = NULL;
+                       writestruct(wd, DATA, "SpaceOops", 1, so);
+               }
+
+               /* restore old treestore */
+               so->treestore = ts;
        } else {
                writestruct(wd, DATA, "SpaceOops", 1, so);
        }
@@ -2425,6 +2442,7 @@
        ScrArea *sa;
        ScrVert *sv;
        ScrEdge *se;
+       LinkNode *tmp_mem_list = NULL;
 
        sc= scrbase->first;
        while (sc) {
@@ -2501,7 +2519,7 @@
                                }
                                else if (sl->spacetype==SPACE_OUTLINER) {
                                        SpaceOops *so= (SpaceOops *)sl;
-                                       write_soops(wd, so);
+                                       write_soops(wd, so, &tmp_mem_list);
                                }
                                else if (sl->spacetype==SPACE_IMAGE) {
                                        SpaceImage *sima= (SpaceImage *)sl;
@@ -2566,6 +2584,8 @@
 
                sc= sc->id.next;
        }
+
+       BLI_linklist_freeN(tmp_mem_list);
        
        /* flush helps the compression for undo-save */
        mywrite(wd, MYWRITE_FLUSH, 0);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to