Tracked down two more memory leaks coming from ext2spice, due to
client data generated by ext2spice and attached to a node's nodeClient record; there is an initNodeClient() routine but no corresponding freeNodeClient() routine. Eventually had to add a callback function passed to EFDone() and EFFlatDone() to clean up these entries. After doing that, valgrind reports clean for all memory allocated within ext2spice (there are other things that are not freed but not related to a specific command, so do not need to be treated as leaks).
This commit is contained in:
parent
7297ca079f
commit
5e3c26c95a
|
|
@ -638,8 +638,8 @@ runexttosim:
|
|||
(void) sprintf( esCapFormat, " GND %%.%dlf\n", esCapAccuracy);
|
||||
EFVisitNodes(simnodeVisit, (ClientData) NULL);
|
||||
|
||||
EFFlatDone();
|
||||
EFDone();
|
||||
EFFlatDone(NULL);
|
||||
EFDone(NULL);
|
||||
|
||||
if (esSimF) fclose(esSimF);
|
||||
if (esLabF) fclose(esLabF);
|
||||
|
|
@ -766,8 +766,8 @@ main(argc, argv)
|
|||
(void) sprintf( esCapFormat, " GND %%.%dlf\n", esCapAccuracy);
|
||||
EFVisitNodes(simnodeVisit, (ClientData) NULL);
|
||||
|
||||
EFFlatDone();
|
||||
EFDone();
|
||||
EFFlatDone(NULL);
|
||||
EFDone(NULL);
|
||||
|
||||
if (esSimF) fclose(esSimF);
|
||||
if (esLabF) fclose(esLabF);
|
||||
|
|
|
|||
|
|
@ -1884,7 +1884,7 @@ esHierVisit(hc, cdata)
|
|||
if ((def != topdef) && (hc->hc_use->use_def->def_flags & DEF_NODEVICES) &&
|
||||
(!doStub))
|
||||
{
|
||||
EFFlatDone();
|
||||
EFFlatDone(esFreeNodeClient);
|
||||
return 0;
|
||||
}
|
||||
else if (doStub)
|
||||
|
|
@ -1987,7 +1987,7 @@ esHierVisit(hc, cdata)
|
|||
#endif
|
||||
}
|
||||
|
||||
EFFlatDone();
|
||||
EFFlatDone(esFreeNodeClient);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,34 @@ int esSpiceDevsMerged;
|
|||
|
||||
devMerge *devMergeList = NULL ;
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* esFreeNodeClient ---
|
||||
*
|
||||
* Free the string spiceNodeName associated with the nodeClient
|
||||
* record that ext2spice allocates per each node structure.
|
||||
*
|
||||
* Returns:
|
||||
* 0 always.
|
||||
*
|
||||
* Side effects:
|
||||
* Frees an allocated string.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
esFreeNodeClient(client)
|
||||
nodeClient *client;
|
||||
{
|
||||
if (client != (ClientData)NULL)
|
||||
if (client->spiceNodeName != NULL)
|
||||
freeMagic((char *)client->spiceNodeName);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -1002,9 +1030,9 @@ runexttospice:
|
|||
if (esFormat == HSPICE)
|
||||
printSubcktDict();
|
||||
|
||||
EFFlatDone();
|
||||
EFFlatDone(esFreeNodeClient);
|
||||
}
|
||||
EFDone();
|
||||
EFDone(esFreeNodeClient);
|
||||
if (esFormat == HSPICE) {
|
||||
HashKill(&subcktNameTable);
|
||||
#ifndef UNSORTED_SUBCKT
|
||||
|
|
@ -1167,8 +1195,8 @@ main(argc, argv)
|
|||
if (esFormat == HSPICE)
|
||||
printSubcktDict();
|
||||
|
||||
EFFlatDone();
|
||||
EFDone();
|
||||
EFFlatDone(esFreeNodeClient);
|
||||
EFDone(esFreeNodeClient);
|
||||
if (esFormat == HSPICE) {
|
||||
HashKill(&subcktNameTable);
|
||||
#ifndef UNSORTED_SUBCKT
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ extern EFNode *spcdevHierSubstrate();
|
|||
extern char *nodeSpiceHierName();
|
||||
extern devMerge *mkDevMerge();
|
||||
extern bool extHierSDAttr();
|
||||
extern int esFreeNodeClient();
|
||||
|
||||
extern bool devIsKilled();
|
||||
extern float getCurDevMult();
|
||||
|
|
|
|||
|
|
@ -1988,18 +1988,30 @@ efFreeNodeTable(table)
|
|||
* Free the circular list of nodes of which 'head' is the head.
|
||||
* Don't free 'head' itself, since it's statically allocated.
|
||||
*
|
||||
* If the client (e.g., ext2spice, ext2sim, ...) allocates memory for a
|
||||
* node, then that client needs to provide a function "func" of the form:
|
||||
*
|
||||
* int func(client)
|
||||
* ClientData client;
|
||||
* {
|
||||
* }
|
||||
*
|
||||
* The return value is unused but should be zero for consistency.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Frees memory.
|
||||
* Frees memory. Calls func() to free additional memory allocated
|
||||
* in the node structure by a client.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
efFreeNodeList(head)
|
||||
efFreeNodeList(head, func)
|
||||
EFNode *head;
|
||||
int (*func)();
|
||||
{
|
||||
EFNode *node;
|
||||
EFAttr *ap;
|
||||
|
|
@ -2010,6 +2022,12 @@ efFreeNodeList(head)
|
|||
{
|
||||
for (ap = node->efnode_attrs; ap; ap = ap->efa_next)
|
||||
freeMagic((char *) ap);
|
||||
if (node->efnode_client != (ClientData)NULL)
|
||||
{
|
||||
if (func != NULL)
|
||||
(*func)(node->efnode_client);
|
||||
freeMagic((char *)node->efnode_client);
|
||||
}
|
||||
freeMagic((char *) node);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ EFInit()
|
|||
*
|
||||
* EFDone --
|
||||
*
|
||||
* Overall cleanup.
|
||||
* Overall cleanup. For use of func(), see efFreeNodeList() in EFbuild.c.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
|
|
@ -95,7 +95,8 @@ EFInit()
|
|||
*/
|
||||
|
||||
void
|
||||
EFDone()
|
||||
EFDone(func)
|
||||
int (*func)();
|
||||
{
|
||||
Connection *conn;
|
||||
HashSearch hs;
|
||||
|
|
@ -111,7 +112,7 @@ EFDone()
|
|||
def = (Def *) HashGetValue(he);
|
||||
freeMagic(def->def_name);
|
||||
efFreeNodeTable(&def->def_nodes);
|
||||
efFreeNodeList(&def->def_firstn);
|
||||
efFreeNodeList(&def->def_firstn, func);
|
||||
efFreeUseTable(&def->def_uses);
|
||||
efFreeDevTable(&def->def_devs);
|
||||
HashKill(&def->def_nodes);
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ EFFlatBuildOneLevel(def, flags)
|
|||
* EFFlatDone --
|
||||
*
|
||||
* Cleanup by removing all memory used by the flattened circuit
|
||||
* representation.
|
||||
* representation. For use of func(), see efFreeNodeList() in EFbuild.c.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
|
|
@ -252,7 +252,8 @@ EFFlatBuildOneLevel(def, flags)
|
|||
*/
|
||||
|
||||
void
|
||||
EFFlatDone()
|
||||
EFFlatDone(func)
|
||||
int (*func)();
|
||||
{
|
||||
#ifdef MALLOCTRACE
|
||||
/* Hash table statistics */
|
||||
|
|
@ -262,7 +263,7 @@ EFFlatDone()
|
|||
|
||||
/* Free temporary storage */
|
||||
efFreeNodeTable(&efNodeHashTable);
|
||||
efFreeNodeList(&efNodeList);
|
||||
efFreeNodeList(&efNodeList, func);
|
||||
HashFreeKill(&efCapHashTable);
|
||||
HashKill(&efNodeHashTable);
|
||||
HashKill(&efDistHashTable);
|
||||
|
|
|
|||
|
|
@ -2172,8 +2172,8 @@ DefWriteCell(def, outName, allSpecial, units)
|
|||
fprintf(f, "END NETS\n\n");
|
||||
|
||||
if (nets.has_nets) {
|
||||
EFFlatDone();
|
||||
EFDone();
|
||||
EFFlatDone(NULL);
|
||||
EFDone(NULL);
|
||||
}
|
||||
|
||||
fprintf(f, "END DESIGN\n\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue