home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / patches / 7.0 / 7.0.135 < prev    next >
Encoding:
Internet Message Format  |  2006-10-14  |  9.8 KB

  1. To: vim-dev@vim.org
  2. Subject: Patch 7.0.135
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=ISO-8859-1
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 7.0.135
  11. Problem:    Crash when garbage collecting list or dict with loop.
  12. Solution:   Don't use DEL_REFCOUNT but don't recurse into Lists and
  13.         Dictionaries when freeing them in the garbage collector.
  14.         Also add allocated Dictionaries to the list of Dictionaries to
  15.         avoid leaking memory.
  16. Files:        src/eval.c, src/proto/eval.pro, src/tag.c
  17.  
  18.  
  19. *** ../vim-7.0.134/src/eval.c    Sun Oct 15 15:10:08 2006
  20. --- src/eval.c    Sun Oct 15 22:30:09 2006
  21. ***************
  22. *** 191,198 ****
  23.   #define FC_RANGE    2        /* function accepts range */
  24.   #define FC_DICT        4        /* Dict function, uses "self" */
  25.   
  26. - #define DEL_REFCOUNT    999999    /* list/dict is being deleted */
  27.   /*
  28.    * All user-defined functions are found in this hashtable.
  29.    */
  30. --- 191,196 ----
  31. ***************
  32. *** 435,441 ****
  33.   static void set_ref_in_list __ARGS((list_T *l, int copyID));
  34.   static void set_ref_in_item __ARGS((typval_T *tv, int copyID));
  35.   static void dict_unref __ARGS((dict_T *d));
  36. ! static void dict_free __ARGS((dict_T *d));
  37.   static dictitem_T *dictitem_alloc __ARGS((char_u *key));
  38.   static dictitem_T *dictitem_copy __ARGS((dictitem_T *org));
  39.   static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item));
  40. --- 433,439 ----
  41.   static void set_ref_in_list __ARGS((list_T *l, int copyID));
  42.   static void set_ref_in_item __ARGS((typval_T *tv, int copyID));
  43.   static void dict_unref __ARGS((dict_T *d));
  44. ! static void dict_free __ARGS((dict_T *d, int recurse));
  45.   static dictitem_T *dictitem_alloc __ARGS((char_u *key));
  46.   static dictitem_T *dictitem_copy __ARGS((dictitem_T *org));
  47.   static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item));
  48. ***************
  49. *** 4899,4905 ****
  50.               {
  51.               if (list_append_tv(l, &item->li_tv) == FAIL)
  52.               {
  53. !                 list_free(l);
  54.                   return FAIL;
  55.               }
  56.               item = item->li_next;
  57. --- 4897,4903 ----
  58.               {
  59.               if (list_append_tv(l, &item->li_tv) == FAIL)
  60.               {
  61. !                 list_free(l, TRUE);
  62.                   return FAIL;
  63.               }
  64.               item = item->li_next;
  65. ***************
  66. *** 5299,5305 ****
  67.       EMSG2(_("E697: Missing end of List ']': %s"), *arg);
  68.   failret:
  69.       if (evaluate)
  70. !         list_free(l);
  71.       return FAIL;
  72.       }
  73.   
  74. --- 5297,5303 ----
  75.       EMSG2(_("E697: Missing end of List ']': %s"), *arg);
  76.   failret:
  77.       if (evaluate)
  78. !         list_free(l, TRUE);
  79.       return FAIL;
  80.       }
  81.   
  82. ***************
  83. *** 5363,5370 ****
  84.   list_unref(l)
  85.       list_T *l;
  86.   {
  87. !     if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0)
  88. !     list_free(l);
  89.   }
  90.   
  91.   /*
  92. --- 5361,5368 ----
  93.   list_unref(l)
  94.       list_T *l;
  95.   {
  96. !     if (l != NULL && --l->lv_refcount <= 0)
  97. !     list_free(l, TRUE);
  98.   }
  99.   
  100.   /*
  101. ***************
  102. *** 5372,5385 ****
  103.    * Ignores the reference count.
  104.    */
  105.       void
  106. ! list_free(l)
  107. !     list_T *l;
  108.   {
  109.       listitem_T *item;
  110.   
  111. -     /* Avoid that recursive reference to the list frees us again. */
  112. -     l->lv_refcount = DEL_REFCOUNT;
  113.       /* Remove the list from the list of lists for garbage collection. */
  114.       if (l->lv_used_prev == NULL)
  115.       first_list = l->lv_used_next;
  116. --- 5370,5381 ----
  117.    * Ignores the reference count.
  118.    */
  119.       void
  120. ! list_free(l, recurse)
  121. !     list_T  *l;
  122. !     int        recurse;    /* Free Lists and Dictionaries recursively. */
  123.   {
  124.       listitem_T *item;
  125.   
  126.       /* Remove the list from the list of lists for garbage collection. */
  127.       if (l->lv_used_prev == NULL)
  128.       first_list = l->lv_used_next;
  129. ***************
  130. *** 5392,5398 ****
  131.       {
  132.       /* Remove the item before deleting it. */
  133.       l->lv_first = item->li_next;
  134. !     listitem_free(item);
  135.       }
  136.       vim_free(l);
  137.   }
  138. --- 5388,5397 ----
  139.       {
  140.       /* Remove the item before deleting it. */
  141.       l->lv_first = item->li_next;
  142. !     if (recurse || (item->li_tv.v_type != VAR_LIST
  143. !                        && item->li_tv.v_type != VAR_DICT))
  144. !         clear_tv(&item->li_tv);
  145. !     vim_free(item);
  146.       }
  147.       vim_free(l);
  148.   }
  149. ***************
  150. *** 6113,6119 ****
  151.       for (dd = first_dict; dd != NULL; )
  152.       if (dd->dv_copyID != copyID)
  153.       {
  154. !         dict_free(dd);
  155.           did_free = TRUE;
  156.   
  157.           /* restart, next dict may also have been freed */
  158. --- 6118,6127 ----
  159.       for (dd = first_dict; dd != NULL; )
  160.       if (dd->dv_copyID != copyID)
  161.       {
  162. !         /* Free the Dictionary and ordinary items it contains, but don't
  163. !          * recurse into Lists and Dictionaries, they will be in the list
  164. !          * of dicts or list of lists. */
  165. !         dict_free(dd, FALSE);
  166.           did_free = TRUE;
  167.   
  168.           /* restart, next dict may also have been freed */
  169. ***************
  170. *** 6130,6136 ****
  171.       for (ll = first_list; ll != NULL; )
  172.       if (ll->lv_copyID != copyID && ll->lv_watch == NULL)
  173.       {
  174. !         list_free(ll);
  175.           did_free = TRUE;
  176.   
  177.           /* restart, next list may also have been freed */
  178. --- 6138,6147 ----
  179.       for (ll = first_list; ll != NULL; )
  180.       if (ll->lv_copyID != copyID && ll->lv_watch == NULL)
  181.       {
  182. !         /* Free the List and ordinary items it contains, but don't recurse
  183. !          * into Lists and Dictionaries, they will be in the list of dicts
  184. !          * or list of lists. */
  185. !         list_free(ll, FALSE);
  186.           did_free = TRUE;
  187.   
  188.           /* restart, next list may also have been freed */
  189. ***************
  190. *** 6223,6233 ****
  191.       d = (dict_T *)alloc(sizeof(dict_T));
  192.       if (d != NULL)
  193.       {
  194. !     /* Add the list to the hashtable for garbage collection. */
  195.       if (first_dict != NULL)
  196.           first_dict->dv_used_prev = d;
  197.       d->dv_used_next = first_dict;
  198.       d->dv_used_prev = NULL;
  199.   
  200.       hash_init(&d->dv_hashtab);
  201.       d->dv_lock = 0;
  202. --- 6234,6245 ----
  203.       d = (dict_T *)alloc(sizeof(dict_T));
  204.       if (d != NULL)
  205.       {
  206. !     /* Add the list to the list of dicts for garbage collection. */
  207.       if (first_dict != NULL)
  208.           first_dict->dv_used_prev = d;
  209.       d->dv_used_next = first_dict;
  210.       d->dv_used_prev = NULL;
  211. +     first_dict = d;
  212.   
  213.       hash_init(&d->dv_hashtab);
  214.       d->dv_lock = 0;
  215. ***************
  216. *** 6245,6252 ****
  217.   dict_unref(d)
  218.       dict_T *d;
  219.   {
  220. !     if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0)
  221. !     dict_free(d);
  222.   }
  223.   
  224.   /*
  225. --- 6257,6264 ----
  226.   dict_unref(d)
  227.       dict_T *d;
  228.   {
  229. !     if (d != NULL && --d->dv_refcount <= 0)
  230. !     dict_free(d, TRUE);
  231.   }
  232.   
  233.   /*
  234. ***************
  235. *** 6254,6269 ****
  236.    * Ignores the reference count.
  237.    */
  238.       static void
  239. ! dict_free(d)
  240. !     dict_T *d;
  241.   {
  242.       int        todo;
  243.       hashitem_T    *hi;
  244.       dictitem_T    *di;
  245.   
  246. -     /* Avoid that recursive reference to the dict frees us again. */
  247. -     d->dv_refcount = DEL_REFCOUNT;
  248.       /* Remove the dict from the list of dicts for garbage collection. */
  249.       if (d->dv_used_prev == NULL)
  250.       first_dict = d->dv_used_next;
  251. --- 6266,6279 ----
  252.    * Ignores the reference count.
  253.    */
  254.       static void
  255. ! dict_free(d, recurse)
  256. !     dict_T  *d;
  257. !     int        recurse;    /* Free Lists and Dictionaries recursively. */
  258.   {
  259.       int        todo;
  260.       hashitem_T    *hi;
  261.       dictitem_T    *di;
  262.   
  263.       /* Remove the dict from the list of dicts for garbage collection. */
  264.       if (d->dv_used_prev == NULL)
  265.       first_dict = d->dv_used_next;
  266. ***************
  267. *** 6283,6289 ****
  268.            * something recursive causing trouble. */
  269.           di = HI2DI(hi);
  270.           hash_remove(&d->dv_hashtab, hi);
  271. !         dictitem_free(di);
  272.           --todo;
  273.       }
  274.       }
  275. --- 6293,6302 ----
  276.            * something recursive causing trouble. */
  277.           di = HI2DI(hi);
  278.           hash_remove(&d->dv_hashtab, hi);
  279. !         if (recurse || (di->di_tv.v_type != VAR_LIST
  280. !                          && di->di_tv.v_type != VAR_DICT))
  281. !         clear_tv(&di->di_tv);
  282. !         vim_free(di);
  283.           --todo;
  284.       }
  285.       }
  286. ***************
  287. *** 6734,6740 ****
  288.       EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg);
  289.   failret:
  290.       if (evaluate)
  291. !         dict_free(d);
  292.       return FAIL;
  293.       }
  294.   
  295. --- 6747,6753 ----
  296.       EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg);
  297.   failret:
  298.       if (evaluate)
  299. !         dict_free(d, TRUE);
  300.       return FAIL;
  301.       }
  302.   
  303. *** ../vim-7.0.134/src/proto/eval.pro    Fri Mar 24 23:16:28 2006
  304. --- src/proto/eval.pro    Sun Oct 15 22:08:11 2006
  305. ***************
  306. *** 44,50 ****
  307.   extern char_u *get_user_var_name __ARGS((expand_T *xp, int idx));
  308.   extern list_T *list_alloc __ARGS((void));
  309.   extern void list_unref __ARGS((list_T *l));
  310. ! extern void list_free __ARGS((list_T *l));
  311.   extern dictitem_T *dict_lookup __ARGS((hashitem_T *hi));
  312.   extern int list_append_dict __ARGS((list_T *list, dict_T *dict));
  313.   extern int garbage_collect __ARGS((void));
  314. --- 44,50 ----
  315.   extern char_u *get_user_var_name __ARGS((expand_T *xp, int idx));
  316.   extern list_T *list_alloc __ARGS((void));
  317.   extern void list_unref __ARGS((list_T *l));
  318. ! extern void list_free __ARGS((list_T *l, int recurse));
  319.   extern dictitem_T *dict_lookup __ARGS((hashitem_T *hi));
  320.   extern int list_append_dict __ARGS((list_T *list, dict_T *dict));
  321.   extern int garbage_collect __ARGS((void));
  322. *** ../vim-7.0.134/src/tag.c    Sun Sep 10 13:56:06 2006
  323. --- src/tag.c    Sun Oct 15 21:44:56 2006
  324. ***************
  325. *** 911,917 ****
  326.   
  327.           set_errorlist(curwin, list, ' ');
  328.   
  329. !         list_free(list);
  330.   
  331.           cur_match = 0;        /* Jump to the first tag */
  332.           }
  333. --- 911,917 ----
  334.   
  335.           set_errorlist(curwin, list, ' ');
  336.   
  337. !         list_free(list, TRUE);
  338.   
  339.           cur_match = 0;        /* Jump to the first tag */
  340.           }
  341. *** ../vim-7.0.134/src/version.c    Sun Oct 15 15:10:08 2006
  342. --- src/version.c    Sun Oct 15 22:01:53 2006
  343. ***************
  344. *** 668,669 ****
  345. --- 668,671 ----
  346.   {   /* Add new patch number below this line */
  347. + /**/
  348. +     135,
  349.   /**/
  350.  
  351. -- 
  352. Well, you come from nothing, you go back to nothing...  What have you
  353. lost?  Nothing!
  354.                 -- Monty Python: The life of Brian
  355.  
  356.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  357. ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  358. \\\        download, build and distribute -- http://www.A-A-P.org        ///
  359.  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
  360.