3e29ad0059ebf3c9b781ac5317e692ae2a2687bb
braney
  Tue Jan 14 23:31:45 2020 -0800
hgCollection fiddles with the settingsHash of trackDb, which might be
cached and made up of memory that shouldn't be freed.   Copy the hash
before fiddling with it.   Found a bug in lmCloneHash (wasn't setting
hash->lm correctly, so increment trackDb version just to make sure cache
will be cleared.

diff --git src/hg/lib/trackDbCache.c src/hg/lib/trackDbCache.c
index d2e9a0b..ca2d949 100644
--- src/hg/lib/trackDbCache.c
+++ src/hg/lib/trackDbCache.c
@@ -37,65 +37,30 @@
 if (superHash == NULL)
     errAbort("parsing supertrack without superHash");
 
 struct trackDb *super = (struct trackDb *)hashFindVal(superHash, tdb->parent->track);
 
 if (super == NULL)
     {
     super = lmCloneTdb(lm, tdb->parent, NULL, NULL);
     hashAdd(superHash, super->track, super);
     }
 lmRefAdd(lm, &super->children, tdb);
 
 return super;
 }
 
-struct hashEl *lmCloneHashElList(struct lm *lm, struct hashEl *list)
-/* Clone a list of hashEl's. */
-{
-struct hashEl *newList = NULL;
-
-for(; list; list = list->next)
-    {
-    struct hashEl *hel = lmAlloc(lm, sizeof(struct hashEl));
-    slAddHead(&newList, hel);
-    hel->name = lmCloneString(lm, list->name);
-    hel->val = lmCloneString(lm, (char *)list->val);  // we're assuming that the values are strings
-    hel->hashVal = list->hashVal;
-    }
-
-return newList;
-}
-
-struct hash *lmCloneHash(struct lm *lm, struct hash *hash)
-/* Clone a hash into local memory. */
-{
-struct hash *newHash = lmAlloc(lm, sizeof(struct hash));
-
-*newHash = *hash;
-newHash->lm = NULL;
-newHash->ownLm = FALSE;
-newHash->next = NULL;
-lmAllocArray(lm, newHash->table, hash->size);
-
-int ii;
-for(ii=0; ii < hash->size; ii++)
-    if (hash->table[ii] != NULL)
-        newHash->table[ii] = lmCloneHashElList(lm, hash->table[ii]);
-
-return newHash;
-}
 
 struct trackDb *lmCloneTdb(struct lm *lm, struct trackDb *tdb, struct trackDb *parent,  struct hash *superHash)
 /* clone a single tdb structure.  Will clone its children if it has any */
 {
 struct trackDb *newTdb = lmAlloc(lm, sizeof(struct trackDb));
 
 *newTdb = *tdb;
 
 if (tdb->subtracks)
     newTdb->subtracks = lmCloneTdbList(lm, tdb->subtracks, newTdb, NULL);
 
 if ((tdb->parent != NULL) && (superHash != NULL))
     {
     newTdb->parent = lmCloneSuper(lm, newTdb, superHash);
     }