Commit 00f76dbf authored by Tom Lane's avatar Tom Lane

Get rid of a bunch of dubious error handling code in pgbench by just erroring

out immediately on any out-of-memory condition.  It's rather pointless to
imagine that pgbench will be able to continue usefully after a malloc
failure, and in any case there were a number of unchecked mallocs.
parent 5a4e19ab
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* A simple benchmark program for PostgreSQL * A simple benchmark program for PostgreSQL
* Originally written by Tatsuo Ishii and enhanced by many contributors. * Originally written by Tatsuo Ishii and enhanced by many contributors.
* *
* $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.100 2010/08/12 20:39:39 tgl Exp $ * $PostgreSQL: pgsql/contrib/pgbench/pgbench.c,v 1.101 2010/08/12 21:10:59 tgl Exp $
* Copyright (c) 2000-2010, PostgreSQL Global Development Group * Copyright (c) 2000-2010, PostgreSQL Global Development Group
* ALL RIGHTS RESERVED; * ALL RIGHTS RESERVED;
* *
...@@ -277,6 +277,53 @@ static char *select_only = { ...@@ -277,6 +277,53 @@ static char *select_only = {
static void setalarm(int seconds); static void setalarm(int seconds);
static void *threadRun(void *arg); static void *threadRun(void *arg);
/*
* routines to check mem allocations and fail noisily.
*/
static void *
xmalloc(size_t size)
{
void *result;
result = malloc(size);
if (!result)
{
fprintf(stderr, "out of memory\n");
exit(1);
}
return result;
}
static void *
xrealloc(void *ptr, size_t size)
{
void *result;
result = realloc(ptr, size);
if (!result)
{
fprintf(stderr, "out of memory\n");
exit(1);
}
return result;
}
static char *
xstrdup(const char *s)
{
char *result;
result = strdup(s);
if (!result)
{
fprintf(stderr, "out of memory\n");
exit(1);
}
return result;
}
static void static void
usage(const char *progname) usage(const char *progname)
{ {
...@@ -480,28 +527,17 @@ putVariable(CState *st, const char *context, char *name, char *value) ...@@ -480,28 +527,17 @@ putVariable(CState *st, const char *context, char *name, char *value)
} }
if (st->variables) if (st->variables)
newvars = (Variable *) realloc(st->variables, newvars = (Variable *) xrealloc(st->variables,
(st->nvariables + 1) * sizeof(Variable)); (st->nvariables + 1) * sizeof(Variable));
else else
newvars = (Variable *) malloc(sizeof(Variable)); newvars = (Variable *) xmalloc(sizeof(Variable));
if (newvars == NULL)
goto out_of_memory;
st->variables = newvars; st->variables = newvars;
var = &newvars[st->nvariables]; var = &newvars[st->nvariables];
var->name = NULL; var->name = xstrdup(name);
var->value = NULL; var->value = xstrdup(value);
if ((var->name = strdup(name)) == NULL ||
(var->value = strdup(value)) == NULL)
{
free(var->name);
free(var->value);
return false;
}
st->nvariables++; st->nvariables++;
...@@ -512,18 +548,14 @@ putVariable(CState *st, const char *context, char *name, char *value) ...@@ -512,18 +548,14 @@ putVariable(CState *st, const char *context, char *name, char *value)
{ {
char *val; char *val;
if ((val = strdup(value)) == NULL) /* dup then free, in case value is pointing at this variable */
return false; val = xstrdup(value);
free(var->value); free(var->value);
var->value = val; var->value = val;
} }
return true; return true;
out_of_memory:
fprintf(stderr, "%s: out of memory for variable '%s'\n", context, name);
return false;
} }
static char * static char *
...@@ -539,9 +571,7 @@ parseVariable(const char *sql, int *eaten) ...@@ -539,9 +571,7 @@ parseVariable(const char *sql, int *eaten)
if (i == 1) if (i == 1)
return NULL; return NULL;
name = malloc(i); name = xmalloc(i);
if (name == NULL)
return NULL;
memcpy(name, &sql[1], i - 1); memcpy(name, &sql[1], i - 1);
name[i - 1] = '\0'; name[i - 1] = '\0';
...@@ -556,16 +586,9 @@ replaceVariable(char **sql, char *param, int len, char *value) ...@@ -556,16 +586,9 @@ replaceVariable(char **sql, char *param, int len, char *value)
if (valueln > len) if (valueln > len)
{ {
char *tmp;
size_t offset = param - *sql; size_t offset = param - *sql;
tmp = realloc(*sql, strlen(*sql) - len + valueln + 1); *sql = xrealloc(*sql, strlen(*sql) - len + valueln + 1);
if (tmp == NULL)
{
free(*sql);
return NULL;
}
*sql = tmp;
param = *sql + offset; param = *sql + offset;
} }
...@@ -606,8 +629,7 @@ assignVariables(CState *st, char *sql) ...@@ -606,8 +629,7 @@ assignVariables(CState *st, char *sql)
continue; continue;
} }
if ((p = replaceVariable(&sql, p, eaten, val)) == NULL) p = replaceVariable(&sql, p, eaten, val);
return NULL;
} }
return sql; return sql;
...@@ -902,13 +924,8 @@ top: ...@@ -902,13 +924,8 @@ top:
{ {
char *sql; char *sql;
if ((sql = strdup(command->argv[0])) == NULL sql = xstrdup(command->argv[0]);
|| (sql = assignVariables(st, sql)) == NULL) sql = assignVariables(st, sql);
{
fprintf(stderr, "out of memory\n");
st->ecnt++;
return true;
}
if (debug) if (debug)
fprintf(stderr, "client %d sending %s\n", st->id, sql); fprintf(stderr, "client %d sending %s\n", st->id, sql);
...@@ -1345,9 +1362,7 @@ parseQuery(Command *cmd, const char *raw_sql) ...@@ -1345,9 +1362,7 @@ parseQuery(Command *cmd, const char *raw_sql)
char *sql, char *sql,
*p; *p;
sql = strdup(raw_sql); sql = xstrdup(raw_sql);
if (sql == NULL)
return false;
cmd->argc = 1; cmd->argc = 1;
p = sql; p = sql;
...@@ -1374,8 +1389,7 @@ parseQuery(Command *cmd, const char *raw_sql) ...@@ -1374,8 +1389,7 @@ parseQuery(Command *cmd, const char *raw_sql)
} }
sprintf(var, "$%d", cmd->argc); sprintf(var, "$%d", cmd->argc);
if ((p = replaceVariable(&sql, p, eaten, var)) == NULL) p = replaceVariable(&sql, p, eaten, var);
return false;
cmd->argv[cmd->argc] = name; cmd->argv[cmd->argc] = name;
cmd->argc++; cmd->argc++;
...@@ -1410,12 +1424,8 @@ process_commands(char *buf) ...@@ -1410,12 +1424,8 @@ process_commands(char *buf)
return NULL; return NULL;
/* Allocate and initialize Command structure */ /* Allocate and initialize Command structure */
my_commands = (Command *) malloc(sizeof(Command)); my_commands = (Command *) xmalloc(sizeof(Command));
if (my_commands == NULL) my_commands->line = xstrdup(buf);
return NULL;
my_commands->line = strdup(buf);
if (my_commands->line == NULL)
return NULL;
my_commands->command_num = num_commands++; my_commands->command_num = num_commands++;
my_commands->type = 0; /* until set */ my_commands->type = 0; /* until set */
my_commands->argc = 0; my_commands->argc = 0;
...@@ -1429,12 +1439,8 @@ process_commands(char *buf) ...@@ -1429,12 +1439,8 @@ process_commands(char *buf)
while (tok != NULL) while (tok != NULL)
{ {
if ((my_commands->argv[j] = strdup(tok)) == NULL) my_commands->argv[j++] = xstrdup(tok);
return NULL;
my_commands->argc++; my_commands->argc++;
j++;
tok = strtok(NULL, delim); tok = strtok(NULL, delim);
} }
...@@ -1443,7 +1449,7 @@ process_commands(char *buf) ...@@ -1443,7 +1449,7 @@ process_commands(char *buf)
if (my_commands->argc < 4) if (my_commands->argc < 4)
{ {
fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]); fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
return NULL; exit(1);
} }
for (j = 4; j < my_commands->argc; j++) for (j = 4; j < my_commands->argc; j++)
...@@ -1455,7 +1461,7 @@ process_commands(char *buf) ...@@ -1455,7 +1461,7 @@ process_commands(char *buf)
if (my_commands->argc < 3) if (my_commands->argc < 3)
{ {
fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]); fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
return NULL; exit(1);
} }
for (j = my_commands->argc < 5 ? 3 : 5; j < my_commands->argc; j++) for (j = my_commands->argc < 5 ? 3 : 5; j < my_commands->argc; j++)
...@@ -1467,7 +1473,7 @@ process_commands(char *buf) ...@@ -1467,7 +1473,7 @@ process_commands(char *buf)
if (my_commands->argc < 2) if (my_commands->argc < 2)
{ {
fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]); fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
return NULL; exit(1);
} }
/* /*
...@@ -1498,7 +1504,7 @@ process_commands(char *buf) ...@@ -1498,7 +1504,7 @@ process_commands(char *buf)
{ {
fprintf(stderr, "%s: unknown time unit '%s' - must be us, ms or s\n", fprintf(stderr, "%s: unknown time unit '%s' - must be us, ms or s\n",
my_commands->argv[0], my_commands->argv[2]); my_commands->argv[0], my_commands->argv[2]);
return NULL; exit(1);
} }
} }
...@@ -1511,7 +1517,7 @@ process_commands(char *buf) ...@@ -1511,7 +1517,7 @@ process_commands(char *buf)
if (my_commands->argc < 3) if (my_commands->argc < 3)
{ {
fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]); fprintf(stderr, "%s: missing argument\n", my_commands->argv[0]);
return NULL; exit(1);
} }
} }
else if (pg_strcasecmp(my_commands->argv[0], "shell") == 0) else if (pg_strcasecmp(my_commands->argv[0], "shell") == 0)
...@@ -1519,13 +1525,13 @@ process_commands(char *buf) ...@@ -1519,13 +1525,13 @@ process_commands(char *buf)
if (my_commands->argc < 1) if (my_commands->argc < 1)
{ {
fprintf(stderr, "%s: missing command\n", my_commands->argv[0]); fprintf(stderr, "%s: missing command\n", my_commands->argv[0]);
return NULL; exit(1);
} }
} }
else else
{ {
fprintf(stderr, "Invalid command %s\n", my_commands->argv[0]); fprintf(stderr, "Invalid command %s\n", my_commands->argv[0]);
return NULL; exit(1);
} }
} }
else else
...@@ -1535,17 +1541,16 @@ process_commands(char *buf) ...@@ -1535,17 +1541,16 @@ process_commands(char *buf)
switch (querymode) switch (querymode)
{ {
case QUERY_SIMPLE: case QUERY_SIMPLE:
if ((my_commands->argv[0] = strdup(p)) == NULL) my_commands->argv[0] = xstrdup(p);
return NULL;
my_commands->argc++; my_commands->argc++;
break; break;
case QUERY_EXTENDED: case QUERY_EXTENDED:
case QUERY_PREPARED: case QUERY_PREPARED:
if (!parseQuery(my_commands, p)) if (!parseQuery(my_commands, p))
return NULL; exit(1);
break; break;
default: default:
return NULL; exit(1);
} }
} }
...@@ -1570,9 +1575,7 @@ process_file(char *filename) ...@@ -1570,9 +1575,7 @@ process_file(char *filename)
} }
alloc_num = COMMANDS_ALLOC_NUM; alloc_num = COMMANDS_ALLOC_NUM;
my_commands = (Command **) malloc(sizeof(Command *) * alloc_num); my_commands = (Command **) xmalloc(sizeof(Command *) * alloc_num);
if (my_commands == NULL)
return false;
if (strcmp(filename, "-") == 0) if (strcmp(filename, "-") == 0)
fd = stdin; fd = stdin;
...@@ -1598,12 +1601,7 @@ process_file(char *filename) ...@@ -1598,12 +1601,7 @@ process_file(char *filename)
if (lineno >= alloc_num) if (lineno >= alloc_num)
{ {
alloc_num += COMMANDS_ALLOC_NUM; alloc_num += COMMANDS_ALLOC_NUM;
my_commands = realloc(my_commands, sizeof(Command *) * alloc_num); my_commands = xrealloc(my_commands, sizeof(Command *) * alloc_num);
if (my_commands == NULL)
{
fclose(fd);
return false;
}
} }
} }
fclose(fd); fclose(fd);
...@@ -1625,13 +1623,8 @@ process_builtin(char *tb) ...@@ -1625,13 +1623,8 @@ process_builtin(char *tb)
char buf[BUFSIZ]; char buf[BUFSIZ];
int alloc_num; int alloc_num;
if (*tb == '\0')
return NULL;
alloc_num = COMMANDS_ALLOC_NUM; alloc_num = COMMANDS_ALLOC_NUM;
my_commands = (Command **) malloc(sizeof(Command *) * alloc_num); my_commands = (Command **) xmalloc(sizeof(Command *) * alloc_num);
if (my_commands == NULL)
return NULL;
lineno = 0; lineno = 0;
...@@ -1662,11 +1655,7 @@ process_builtin(char *tb) ...@@ -1662,11 +1655,7 @@ process_builtin(char *tb)
if (lineno >= alloc_num) if (lineno >= alloc_num)
{ {
alloc_num += COMMANDS_ALLOC_NUM; alloc_num += COMMANDS_ALLOC_NUM;
my_commands = realloc(my_commands, sizeof(Command *) * alloc_num); my_commands = xrealloc(my_commands, sizeof(Command *) * alloc_num);
if (my_commands == NULL)
{
return NULL;
}
} }
} }
...@@ -1831,14 +1820,8 @@ main(int argc, char **argv) ...@@ -1831,14 +1820,8 @@ main(int argc, char **argv)
else if ((env = getenv("PGUSER")) != NULL && *env != '\0') else if ((env = getenv("PGUSER")) != NULL && *env != '\0')
login = env; login = env;
state = (CState *) malloc(sizeof(CState)); state = (CState *) xmalloc(sizeof(CState));
if (state == NULL) memset(state, 0, sizeof(CState));
{
fprintf(stderr, "Couldn't allocate memory for state\n");
exit(1);
}
memset(state, 0, sizeof(*state));
while ((c = getopt(argc, argv, "ih:nvp:dSNc:j:Crs:t:T:U:lf:D:F:M:")) != -1) while ((c = getopt(argc, argv, "ih:nvp:dSNc:j:Crs:t:T:U:lf:D:F:M:")) != -1)
{ {
...@@ -2051,14 +2034,8 @@ main(int argc, char **argv) ...@@ -2051,14 +2034,8 @@ main(int argc, char **argv)
if (nclients > 1) if (nclients > 1)
{ {
state = (CState *) realloc(state, sizeof(CState) * nclients); state = (CState *) xrealloc(state, sizeof(CState) * nclients);
if (state == NULL) memset(state + 1, 0, sizeof(CState) * (nclients - 1));
{
fprintf(stderr, "Couldn't allocate memory for state\n");
exit(1);
}
memset(state + 1, 0, sizeof(*state) * (nclients - 1));
/* copy any -D switch values to all clients */ /* copy any -D switch values to all clients */
for (i = 1; i < nclients; i++) for (i = 1; i < nclients; i++)
...@@ -2181,7 +2158,7 @@ main(int argc, char **argv) ...@@ -2181,7 +2158,7 @@ main(int argc, char **argv)
} }
/* set up thread data structures */ /* set up thread data structures */
threads = (TState *) malloc(sizeof(TState) * nthreads); threads = (TState *) xmalloc(sizeof(TState) * nthreads);
for (i = 0; i < nthreads; i++) for (i = 0; i < nthreads; i++)
{ {
TState *thread = &threads[i]; TState *thread = &threads[i];
...@@ -2196,9 +2173,9 @@ main(int argc, char **argv) ...@@ -2196,9 +2173,9 @@ main(int argc, char **argv)
int t; int t;
thread->exec_elapsed = (instr_time *) thread->exec_elapsed = (instr_time *)
malloc(sizeof(instr_time) * num_commands); xmalloc(sizeof(instr_time) * num_commands);
thread->exec_count = (int *) thread->exec_count = (int *)
malloc(sizeof(int) * num_commands); xmalloc(sizeof(int) * num_commands);
for (t = 0; t < num_commands; t++) for (t = 0; t < num_commands; t++)
{ {
...@@ -2289,7 +2266,7 @@ threadRun(void *arg) ...@@ -2289,7 +2266,7 @@ threadRun(void *arg)
int remains = nstate; /* number of remaining clients */ int remains = nstate; /* number of remaining clients */
int i; int i;
result = malloc(sizeof(TResult)); result = xmalloc(sizeof(TResult));
INSTR_TIME_SET_ZERO(result->conn_time); INSTR_TIME_SET_ZERO(result->conn_time);
/* open log file if requested */ /* open log file if requested */
...@@ -2503,8 +2480,12 @@ pthread_create(pthread_t *thread, ...@@ -2503,8 +2480,12 @@ pthread_create(pthread_t *thread,
void *ret; void *ret;
instr_time start_time; instr_time start_time;
th = (fork_pthread *) malloc(sizeof(fork_pthread)); th = (fork_pthread *) xmalloc(sizeof(fork_pthread));
pipe(th->pipes); if (pipe(th->pipes) < 0)
{
free(th);
return errno;
}
th->pid = fork(); th->pid = fork();
if (th->pid == -1) /* error */ if (th->pid == -1) /* error */
...@@ -2558,7 +2539,7 @@ pthread_join(pthread_t th, void **thread_return) ...@@ -2558,7 +2539,7 @@ pthread_join(pthread_t th, void **thread_return)
if (thread_return != NULL) if (thread_return != NULL)
{ {
/* assume result is TResult */ /* assume result is TResult */
*thread_return = malloc(sizeof(TResult)); *thread_return = xmalloc(sizeof(TResult));
if (read(th->pipes[0], *thread_return, sizeof(TResult)) != sizeof(TResult)) if (read(th->pipes[0], *thread_return, sizeof(TResult)) != sizeof(TResult))
{ {
free(*thread_return); free(*thread_return);
...@@ -2626,7 +2607,7 @@ pthread_create(pthread_t *thread, ...@@ -2626,7 +2607,7 @@ pthread_create(pthread_t *thread,
int save_errno; int save_errno;
win32_pthread *th; win32_pthread *th;
th = (win32_pthread *) malloc(sizeof(win32_pthread)); th = (win32_pthread *) xmalloc(sizeof(win32_pthread));
th->routine = start_routine; th->routine = start_routine;
th->arg = arg; th->arg = arg;
th->result = NULL; th->result = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment