From: Igor <igor@sba.miami.edu>
Subject: [PATCHES] pg_dump memory leak patch This patch fixes a HUGE memory leak problem in pg_dump. Pretty much anything that was allocated was never freed and Purify reported about 40% possible memory leak and 6% actual leak. I added functions to clear out all the allocated structures. After the patch Purify returns 0 for number of bytes leaked...
This commit is contained in:
parent
a27fafecc5
commit
f9f98e3aff
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.11 1997/04/12 09:23:59 scrappy Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.12 1997/06/02 02:51:49 scrappy Exp $
|
||||||
*
|
*
|
||||||
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
|
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
|
||||||
*
|
*
|
||||||
@ -203,12 +203,12 @@ dumpSchema(FILE *fout,
|
|||||||
int numInherits;
|
int numInherits;
|
||||||
int numAggregates;
|
int numAggregates;
|
||||||
int numOperators;
|
int numOperators;
|
||||||
TypeInfo *tinfo;
|
TypeInfo *tinfo=NULL;
|
||||||
FuncInfo *finfo;
|
FuncInfo *finfo=NULL;
|
||||||
AggInfo *agginfo;
|
AggInfo *agginfo=NULL;
|
||||||
TableInfo *tblinfo;
|
TableInfo *tblinfo=NULL;
|
||||||
InhInfo *inhinfo;
|
InhInfo *inhinfo=NULL;
|
||||||
OprInfo *oprinfo;
|
OprInfo *oprinfo=NULL;
|
||||||
|
|
||||||
if (g_verbose) fprintf(stderr,"%s reading user-defined types %s\n",
|
if (g_verbose) fprintf(stderr,"%s reading user-defined types %s\n",
|
||||||
g_comment_start, g_comment_end);
|
g_comment_start, g_comment_end);
|
||||||
@ -274,10 +274,14 @@ if (!tablename && fout) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*numTablesPtr = numTables;
|
*numTablesPtr = numTables;
|
||||||
|
clearAggInfo(agginfo,numAggregates);
|
||||||
|
clearOprInfo(oprinfo,numOperators);
|
||||||
|
clearTypeInfo(tinfo, numTypes);
|
||||||
|
clearFuncInfo(finfo,numFuncs);
|
||||||
|
clearInhInfo(inhinfo,numInherits);
|
||||||
return tblinfo;
|
return tblinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dumpSchemaIdx:
|
* dumpSchemaIdx:
|
||||||
* dump indexes at the end for performance
|
* dump indexes at the end for performance
|
||||||
@ -300,6 +304,7 @@ dumpSchemaIdx(FILE *fout, int *numTablesPtr, const char *tablename,
|
|||||||
g_comment_start, g_comment_end);
|
g_comment_start, g_comment_end);
|
||||||
dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename);
|
dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename);
|
||||||
}
|
}
|
||||||
|
clearIndInfo(indinfo,numIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flagInhAttrs -
|
/* flagInhAttrs -
|
||||||
@ -409,9 +414,3 @@ isArchiveName(const char* relname)
|
|||||||
{
|
{
|
||||||
return (strlen(relname) > 1 && relname[1] == ',');
|
return (strlen(relname) > 1 && relname[1] == ',');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.28 1997/05/06 05:20:18 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.29 1997/06/02 02:51:53 scrappy Exp $
|
||||||
*
|
*
|
||||||
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
|
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
|
||||||
*
|
*
|
||||||
@ -40,6 +40,10 @@
|
|||||||
*
|
*
|
||||||
* - Fixed ouput lengths for char and varchar type where the length is variable (-1)
|
* - Fixed ouput lengths for char and varchar type where the length is variable (-1)
|
||||||
*
|
*
|
||||||
|
* Modifications - 6/1/97 - igor@sba.miami.edu
|
||||||
|
* - Added functions to free allocated memory used for retrieving
|
||||||
|
* indices,tables,inheritance,types,functions and aggregates.
|
||||||
|
* No more leaks reported by Purify.
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -230,7 +234,6 @@ dumpClasses_nodumpData(FILE *fout, const char *classname, const bool oids) {
|
|||||||
}
|
}
|
||||||
fprintf(fout, "\\.\n");
|
fprintf(fout, "\\.\n");
|
||||||
}
|
}
|
||||||
PQclear(res);
|
|
||||||
ret = PQendcopy(res->conn);
|
ret = PQendcopy(res->conn);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf(stderr, "SQL query to dump the contents of Table %s "
|
fprintf(stderr, "SQL query to dump the contents of Table %s "
|
||||||
@ -239,8 +242,10 @@ dumpClasses_nodumpData(FILE *fout, const char *classname, const bool oids) {
|
|||||||
"Explanation from backend: '%s'.\n"
|
"Explanation from backend: '%s'.\n"
|
||||||
"The query was: '%s'.\n",
|
"The query was: '%s'.\n",
|
||||||
classname, PQerrorMessage(g_conn), query);
|
classname, PQerrorMessage(g_conn), query);
|
||||||
|
if(res) PQclear(res);
|
||||||
exit_nicely(g_conn);
|
exit_nicely(g_conn);
|
||||||
}
|
}
|
||||||
|
if(res) PQclear(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,12 +510,11 @@ main(int argc, char** argv)
|
|||||||
|
|
||||||
fflush(g_fout);
|
fflush(g_fout);
|
||||||
fclose(g_fout);
|
fclose(g_fout);
|
||||||
|
clearTableInfo(tblinfo, numTables);
|
||||||
PQfinish(g_conn);
|
PQfinish(g_conn);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getTypes:
|
* getTypes:
|
||||||
* read all base types in the system catalogs and return them in the
|
* read all base types in the system catalogs and return them in the
|
||||||
@ -722,6 +726,137 @@ getOperators(int *numOprs)
|
|||||||
return oprinfo;
|
return oprinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearTypeInfo(TypeInfo *tp, int numTypes)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0;i<numTypes;++i) {
|
||||||
|
if(tp[i].oid) free(tp[i].oid);
|
||||||
|
if(tp[i].typowner) free(tp[i].typowner);
|
||||||
|
if(tp[i].typname) free(tp[i].typname);
|
||||||
|
if(tp[i].typlen) free(tp[i].typlen);
|
||||||
|
if(tp[i].typprtlen) free(tp[i].typprtlen);
|
||||||
|
if(tp[i].typinput) free(tp[i].typinput);
|
||||||
|
if(tp[i].typoutput) free(tp[i].typoutput);
|
||||||
|
if(tp[i].typreceive) free(tp[i].typreceive);
|
||||||
|
if(tp[i].typsend) free(tp[i].typsend);
|
||||||
|
if(tp[i].typelem) free(tp[i].typelem);
|
||||||
|
if(tp[i].typdelim) free(tp[i].typdelim);
|
||||||
|
if(tp[i].typdefault) free(tp[i].typdefault);
|
||||||
|
if(tp[i].typrelid) free(tp[i].typrelid);
|
||||||
|
}
|
||||||
|
free(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearFuncInfo (FuncInfo *fun, int numFuncs)
|
||||||
|
{
|
||||||
|
int i,a;
|
||||||
|
if(!fun) return;
|
||||||
|
for(i=0;i<numFuncs;++i) {
|
||||||
|
if(fun[i].oid) free(fun[i].oid);
|
||||||
|
if(fun[i].proname) free(fun[i].proname);
|
||||||
|
if(fun[i].proowner) free(fun[i].proowner);
|
||||||
|
for(a=0;a<8;++a)
|
||||||
|
if(fun[i].argtypes[a]) free(fun[i].argtypes[a]);
|
||||||
|
if(fun[i].prorettype) free(fun[i].prorettype);
|
||||||
|
if(fun[i].prosrc) free(fun[i].prosrc);
|
||||||
|
if(fun[i].probin) free(fun[i].probin);
|
||||||
|
}
|
||||||
|
free(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearTableInfo(TableInfo *tblinfo, int numTables)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
for(i=0;i<numTables;++i) {
|
||||||
|
if(tblinfo[i].oid) free (tblinfo[i].oid);
|
||||||
|
if(tblinfo[i].relname) free (tblinfo[i].relname);
|
||||||
|
if(tblinfo[i].relarch) free (tblinfo[i].relarch);
|
||||||
|
if(tblinfo[i].relacl) free (tblinfo[i].relacl);
|
||||||
|
for (j=0;j<tblinfo[i].numatts;j++) {
|
||||||
|
if(tblinfo[i].attnames[j]) free (tblinfo[i].attnames[j]);
|
||||||
|
if(tblinfo[i].typnames[j]) free (tblinfo[i].typnames[j]);
|
||||||
|
}
|
||||||
|
if(tblinfo[i].attlen) free((int *)tblinfo[i].attlen);
|
||||||
|
if(tblinfo[i].inhAttrs) free((int *)tblinfo[i].inhAttrs);
|
||||||
|
if(tblinfo[i].attnames) free (tblinfo[i].attnames);
|
||||||
|
if(tblinfo[i].typnames) free (tblinfo[i].typnames);
|
||||||
|
}
|
||||||
|
free(tblinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearInhInfo (InhInfo *inh, int numInherits) {
|
||||||
|
int i;
|
||||||
|
if(!inh) return;
|
||||||
|
for(i=0;i<numInherits;++i) {
|
||||||
|
if(inh[i].oid) free(inh[i].oid);
|
||||||
|
if(inh[i].inhrel) free(inh[i].inhrel);
|
||||||
|
if(inh[i].inhparent) free(inh[i].inhparent);}
|
||||||
|
free(inh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearOprInfo(OprInfo *opr, int numOprs){
|
||||||
|
int i;
|
||||||
|
if(!opr) return;
|
||||||
|
for(i=0;i<numOprs;++i) {
|
||||||
|
if(opr[i].oid) free(opr[i].oid);
|
||||||
|
if(opr[i].oprname) free(opr[i].oprname);
|
||||||
|
if(opr[i].oprkind) free(opr[i].oprkind);
|
||||||
|
if(opr[i].oprcode) free(opr[i].oprcode);
|
||||||
|
if(opr[i].oprleft) free(opr[i].oprleft);
|
||||||
|
if(opr[i].oprright) free(opr[i].oprright);
|
||||||
|
if(opr[i].oprcom) free(opr[i].oprcom);
|
||||||
|
if(opr[i].oprnegate) free(opr[i].oprnegate);
|
||||||
|
if(opr[i].oprrest) free(opr[i].oprrest);
|
||||||
|
if(opr[i].oprjoin) free(opr[i].oprjoin);
|
||||||
|
if(opr[i].oprcanhash) free(opr[i].oprcanhash);
|
||||||
|
if(opr[i].oprlsortop) free(opr[i].oprlsortop);
|
||||||
|
if(opr[i].oprrsortop) free(opr[i].oprrsortop);
|
||||||
|
}
|
||||||
|
free(opr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearIndInfo(IndInfo *ind, int numIndices)
|
||||||
|
{
|
||||||
|
int i,a;
|
||||||
|
if(!ind) return;
|
||||||
|
for(i=0;i<numIndices;++i) {
|
||||||
|
if(ind[i].indexrelname) free(ind[i].indexrelname);
|
||||||
|
if(ind[i].indrelname) free(ind[i].indrelname);
|
||||||
|
if(ind[i].indamname) free(ind[i].indamname);
|
||||||
|
if(ind[i].indproc) free(ind[i].indproc);
|
||||||
|
if(ind[i].indisunique) free(ind[i].indisunique);
|
||||||
|
for(a=0;a<INDEX_MAX_KEYS;++a) {
|
||||||
|
if(ind[i].indkey[a]) free(ind[i].indkey[a]);
|
||||||
|
if(ind[i].indclass[a]) free(ind[i].indclass[a]);}
|
||||||
|
}
|
||||||
|
free(ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearAggInfo(AggInfo *agginfo, int numArgs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if(!agginfo) return;
|
||||||
|
for(i=0;i<numArgs;++i) {
|
||||||
|
if(agginfo[i].oid) free (agginfo[i].oid);
|
||||||
|
if(agginfo[i].aggname) free (agginfo[i].aggname);
|
||||||
|
if(agginfo[i].aggtransfn1) free (agginfo[i].aggtransfn1);
|
||||||
|
if(agginfo[i].aggtransfn2) free (agginfo[i].aggtransfn2);
|
||||||
|
if(agginfo[i].aggfinalfn) free (agginfo[i].aggfinalfn);
|
||||||
|
if(agginfo[i].aggtranstype1) free (agginfo[i].aggtranstype1);
|
||||||
|
if(agginfo[i].aggbasetype) free (agginfo[i].aggbasetype);
|
||||||
|
if(agginfo[i].aggtranstype2) free (agginfo[i].aggtranstype2);
|
||||||
|
if(agginfo[i].agginitval1) free (agginfo[i].agginitval1);
|
||||||
|
if(agginfo[i].agginitval2) free (agginfo[i].agginitval2);
|
||||||
|
}
|
||||||
|
free (agginfo);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getAggregates:
|
* getAggregates:
|
||||||
@ -778,7 +913,7 @@ getAggregates(int *numAggs)
|
|||||||
*numAggs = ntups;
|
*numAggs = ntups;
|
||||||
|
|
||||||
agginfo = (AggInfo*)malloc(ntups * sizeof(AggInfo));
|
agginfo = (AggInfo*)malloc(ntups * sizeof(AggInfo));
|
||||||
|
|
||||||
i_oid = PQfnumber(res,"oid");
|
i_oid = PQfnumber(res,"oid");
|
||||||
i_aggname = PQfnumber(res,"aggname");
|
i_aggname = PQfnumber(res,"aggname");
|
||||||
i_aggtransfn1 = PQfnumber(res,"aggtransfn1");
|
i_aggtransfn1 = PQfnumber(res,"aggtransfn1");
|
||||||
@ -1207,7 +1342,7 @@ getIndices(int *numIndices)
|
|||||||
}
|
}
|
||||||
PQclear(res);
|
PQclear(res);
|
||||||
res = PQexec(g_conn,"end");
|
res = PQexec(g_conn,"end");
|
||||||
|
if(res) PQclear(res);
|
||||||
return indinfo;
|
return indinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,13 +5,17 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_dump.h,v 1.14 1997/05/07 02:59:59 scrappy Exp $
|
* $Id: pg_dump.h,v 1.15 1997/06/02 02:52:06 scrappy Exp $
|
||||||
*
|
*
|
||||||
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
|
* Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
|
||||||
*
|
*
|
||||||
* - Fixed dumpTable output to output lengths for char and varchar types!
|
* - Fixed dumpTable output to output lengths for char and varchar types!
|
||||||
* - Added single. quote to twin single quote expansion for 'insert' string
|
* - Added single. quote to twin single quote expansion for 'insert' string
|
||||||
* mode.
|
* mode.
|
||||||
|
*
|
||||||
|
* Modifications - 6/1/97 - igor@sba.miami.edu
|
||||||
|
* - Added extern's for the functions that clear allocated memory
|
||||||
|
* in pg_dump.c
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -86,9 +90,9 @@ typedef struct _inhInfo {
|
|||||||
typedef struct _indInfo {
|
typedef struct _indInfo {
|
||||||
char *indexrelname; /* name of the secondary index class */
|
char *indexrelname; /* name of the secondary index class */
|
||||||
char *indrelname; /* name of the indexed heap class */
|
char *indrelname; /* name of the indexed heap class */
|
||||||
char *indamname; /* name of the access method (e.g. btree, rtree, etc.) */
|
char *indamname; /* name of the access method (e.g. btree, rtree, etc.) */
|
||||||
char *indproc; /* oid of the function to compute the index, 0 if none*/
|
char *indproc; /* oid of the function to compute the index, 0 if none*/
|
||||||
char *indkey[INDEX_MAX_KEYS]; /* attribute numbers of the key attributes */
|
char *indkey[INDEX_MAX_KEYS]; /* attribute numbers of the key attributes */
|
||||||
char *indclass[INDEX_MAX_KEYS]; /* opclass of the keys */
|
char *indclass[INDEX_MAX_KEYS]; /* opclass of the keys */
|
||||||
char *indisunique; /* is this index unique? */
|
char *indisunique; /* is this index unique? */
|
||||||
} IndInfo;
|
} IndInfo;
|
||||||
@ -179,6 +183,15 @@ extern bool isViewRule(char *relname);
|
|||||||
extern TypeInfo* getTypes(int *numTypes);
|
extern TypeInfo* getTypes(int *numTypes);
|
||||||
extern FuncInfo* getFuncs(int *numFuncs);
|
extern FuncInfo* getFuncs(int *numFuncs);
|
||||||
extern AggInfo* getAggregates(int *numAggregates);
|
extern AggInfo* getAggregates(int *numAggregates);
|
||||||
|
|
||||||
|
extern void clearAggInfo(AggInfo*, int);
|
||||||
|
extern void clearFuncInfo(FuncInfo*, int);
|
||||||
|
extern void clearInhInfo(InhInfo*, int);
|
||||||
|
extern void clearIndInfo(IndInfo*, int);
|
||||||
|
extern void clearOprInfo(OprInfo*, int);
|
||||||
|
extern void clearTypeInfo(TypeInfo*, int);
|
||||||
|
extern void clearTableInfo(TableInfo*, int);
|
||||||
|
|
||||||
extern OprInfo* getOperators(int *numOperators);
|
extern OprInfo* getOperators(int *numOperators);
|
||||||
extern TableInfo* getTables(int *numTables);
|
extern TableInfo* getTables(int *numTables);
|
||||||
extern InhInfo* getInherits(int *numInherits);
|
extern InhInfo* getInherits(int *numInherits);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user