PQconnectdbParams returns exit value 01 (from gdb).

Lists: pgsql-interfaces
From: Andrei Petru Mura <mapandrei(at)gmail(dot)com>
To: pgsql-interfaces(at)postgresql(dot)org
Subject: PQconnectdbParams returns exit value 01 (from gdb).
Date: 2013-02-25 10:42:10
Message-ID: CAK18DJUsbdMYS3m-7az4Zc32S-AurcMZG7MkoQ5G3SCub_1-fg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-interfaces

I'm trying to create a connection to my database with libpq. Bellow is my
code:

PGconn *connect(char *file_path) {
const char **keywords;
const char **values;
char *line = malloc(LINE_SIZE);
char *prop, *val, *tmp;
int i = 0, j = 0, k = 0;
FILE *creds = fopen(file_path, "r");

if (creds == NULL) {
LOG("%s", "error: cannot open credentials file.\n");
exit(1);
}

keywords = malloc(6 * sizeof(char *));
values = malloc(6 * sizeof(char *));

while (fgets(line, LINE_SIZE, creds) != NULL) {
if (line[strlen(line) - 1] == '\n')
line[strlen(line) - 1] = '\0';
prop = line;
while(*(prop++) != '=') {
i++;
}
tmp = prop;
prop = malloc(i + 1);
strncpy(prop, line, i);
prop[i] = '\0';
keywords[j++] = prop;
val = malloc(strlen(line) - strlen(prop) + 1);
strcpy(val, tmp);
values[k++] = val;
i = 0;
}

keywords[++j] = NULL;
values[++k] = NULL;
printf("%s %s %s %s %s\n", keywords[0], keywords[1], keywords[2],
keywords[3], keywords[4]); //everything is printed well here
printf("%s %s %s %s %s\n", values[0], values[1], values[2], values[3],
values[4]); //here also

PGconn *conn = PQconnectdbParams(keywords, values, 1);

if (PQstatus(conn) != CONNECTION_OK) {
fprintf(stderr, "%s\n", PQerrorMessage(conn));
exit(1);
}

return conn;

}

If I run that code from main(), the printf works fine and nothing else is
printed after. But trying to use that connection, I realized that in fact
the PQconnectdbParams function returns value 01 (after debugging with gdb).

If I try to connect my database with the credentials from specified file,
it works well.

Can anybody help me on solving that issue?


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Andrei Petru Mura <mapandrei(at)gmail(dot)com>
Cc: pgsql-interfaces(at)postgresql(dot)org
Subject: Re: PQconnectdbParams returns exit value 01 (from gdb).
Date: 2013-02-25 11:13:24
Message-ID: 19857.1361790804@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-interfaces

Andrei Petru Mura <mapandrei(at)gmail(dot)com> writes:
> I'm trying to create a connection to my database with libpq. Bellow is my
> code:

> keywords = malloc(6 * sizeof(char *));
> values = malloc(6 * sizeof(char *));

That looks less than safe ... what happens if you have more than five
lines in the creds file?

> while (fgets(line, LINE_SIZE, creds) != NULL) {
> if (line[strlen(line) - 1] == '\n')
> line[strlen(line) - 1] = '\0';
> prop = line;
> while(*(prop++) != '=') {
> i++;
> }
> tmp = prop;
> prop = malloc(i + 1);
> strncpy(prop, line, i);
> prop[i] = '\0';
> keywords[j++] = prop;
> val = malloc(strlen(line) - strlen(prop) + 1);
> strcpy(val, tmp);
> values[k++] = val;
> i = 0;
> }

This has got a few issues, like it'll die badly if there's no '='
in a line, and not behave too well if a line overruns the fixed
buffer length.

> keywords[++j] = NULL;
> values[++k] = NULL;

But your real problem is here, where you're leaving undefined holes
in the arrays. These should be j++ and k++, not ++j and ++k.
If malloc doesn't give you back all-zeroes storage, PQconnectdbParams
will be led to try to dereference garbage pointer values, resulting
in your SIGSEGVs.

regards, tom lane