Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit fe0e0b4

Browse files
committed
Fix memory leak in pgbench
Commit 25ee705 introduced a memory leak in pgbench: some PGresult structs were not being freed during error bailout, because we're now doing more PQgetResult() calls than previously. Since there's more cleanup code outside the discard_response() routine than in it, refactor the cleanup code, removing the routine. This has little effect currently, since we abandon processing after hitting errors, but if we ever get further pgbench features (such as testing for serializable transactions), it'll matter. Per Coverity. Reviewed-by: Michaël Paquier
1 parent a2418f9 commit fe0e0b4

File tree

1 file changed

+18
-30
lines changed

1 file changed

+18
-30
lines changed

src/bin/pgbench/pgbench.c

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,20 +1214,6 @@ doConnect(void)
12141214
return conn;
12151215
}
12161216

1217-
/* throw away response from backend */
1218-
static void
1219-
discard_response(CState *state)
1220-
{
1221-
PGresult *res;
1222-
1223-
do
1224-
{
1225-
res = PQgetResult(state->con);
1226-
if (res)
1227-
PQclear(res);
1228-
} while (res);
1229-
}
1230-
12311217
/* qsort comparator for Variable array */
12321218
static int
12331219
compareVariableNames(const void *v1, const void *v2)
@@ -2732,14 +2718,15 @@ static bool
27322718
readCommandResponse(CState *st, char *varprefix)
27332719
{
27342720
PGresult *res;
2721+
PGresult *next_res;
27352722
int qrynum = 0;
27362723

27372724
res = PQgetResult(st->con);
27382725

27392726
while (res != NULL)
27402727
{
27412728
/* look now at the next result to know whether it is the last */
2742-
PGresult *next_res = PQgetResult(st->con);
2729+
next_res = PQgetResult(st->con);
27432730
bool is_last = (next_res == NULL);
27442731

27452732
switch (PQresultStatus(res))
@@ -2751,8 +2738,7 @@ readCommandResponse(CState *st, char *varprefix)
27512738
fprintf(stderr,
27522739
"client %d script %d command %d query %d: expected one row, got %d\n",
27532740
st->id, st->use_file, st->command, qrynum, 0);
2754-
st->ecnt++;
2755-
return false;
2741+
goto error;
27562742
}
27572743
break;
27582744

@@ -2764,10 +2750,7 @@ readCommandResponse(CState *st, char *varprefix)
27642750
fprintf(stderr,
27652751
"client %d script %d command %d query %d: expected one row, got %d\n",
27662752
st->id, st->use_file, st->command, qrynum, PQntuples(res));
2767-
st->ecnt++;
2768-
PQclear(res);
2769-
discard_response(st);
2770-
return false;
2753+
goto error;
27712754
}
27722755

27732756
/* store results into variables */
@@ -2788,10 +2771,7 @@ readCommandResponse(CState *st, char *varprefix)
27882771
"client %d script %d command %d query %d: error storing into variable %s\n",
27892772
st->id, st->use_file, st->command, qrynum,
27902773
varname);
2791-
st->ecnt++;
2792-
PQclear(res);
2793-
discard_response(st);
2794-
return false;
2774+
goto error;
27952775
}
27962776

27972777
if (*varprefix != '\0')
@@ -2807,10 +2787,7 @@ readCommandResponse(CState *st, char *varprefix)
28072787
"client %d script %d aborted in command %d query %d: %s",
28082788
st->id, st->use_file, st->command, qrynum,
28092789
PQerrorMessage(st->con));
2810-
st->ecnt++;
2811-
PQclear(res);
2812-
discard_response(st);
2813-
return false;
2790+
goto error;
28142791
}
28152792

28162793
PQclear(res);
@@ -2826,8 +2803,19 @@ readCommandResponse(CState *st, char *varprefix)
28262803
}
28272804

28282805
return true;
2829-
}
28302806

2807+
error:
2808+
st->ecnt++;
2809+
PQclear(res);
2810+
PQclear(next_res);
2811+
do
2812+
{
2813+
res = PQgetResult(st->con);
2814+
PQclear(res);
2815+
} while (res);
2816+
2817+
return false;
2818+
}
28312819

28322820
/*
28332821
* Parse the argument to a \sleep command, and return the requested amount

0 commit comments

Comments
 (0)