segfault which isn't supposed to happen (including example code)

From: eric <plukje(at)gmx(dot)net>
To: pgsql-bugs(at)postgresql(dot)org
Subject: segfault which isn't supposed to happen (including example code)
Date: 2002-07-08 14:41:01
Message-ID: 3D29A47D.8090909@gmx.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

hello,

this segfault is all about PQclear();

according to the docs libpq-exec.html

#

PQclear Frees the storage associated with the PGresult. Every query
result should be freed via PQclear when it is no longer needed.

void PQclear(PQresult *res);

You can keep a PGresult object around for as long as you need it; it
does not go away when you issue a new query, nor even if you close the
connection. To get rid of it, you must call PQclear. Failure to do this
will result in memory leaks in the frontend application.

#

I've been playing with the pg example, writing some functions for later
inclusion into a project i'm working on when all of a sudden my
(incredibly simple) program started to segfault. I checked my code, I
let other people check my code, I asked on irc... so far, I can't find
bug on my side, so I suppose it's a bug inside PQclear();
This only happened to me when the PQresult *res was just made and hadn't
been used before. The example code should give more clarity (please
compile as given). Note that using something as

res = PQmakeEmptyPGresult(conn, status);
PQclear(res);

first prevents the program from segfaulting, however, it should have not
segfaulted in the first place.

version used to compile and run are below.
postgres:
(PostgreSQL) 7.2.1
glibc:
GNU C Library stable release version 2.2.4 Compiled by GNU CC version
2.95.3 20010315 (release).Compiled on a Linux 2.4.14 system on 2001-11-09.
gcc:
gcc 2.95.3
kernel:
Linux pathfinder 2.4.18 #1 SMP Fri Mar 22 17:10:20 CET 2002 i686 unknown
build script used to compile this program:
rm pqtest
gcc -g -Wall -I /opt/postgresql/include -L /opt/postgresql/lib -lpgeasy
-lpq pqtest.c -o pqtest

I hope you can determine what is going wrong, please keep me informed
should you be able to find the cause of this.

Kind regards,

Eric van Lent

note: I also included the code as attachment

*/ CODE START */
#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"
#include <string.h>

int DBinsertCmd(char *, char *, PGconn *, PGresult *);
int DBcontrol();

static void exit_nicely(PGconn *conn)
{
PQfinish(conn);
exit(1);
}

int main()
{
int i = 30;
int n = 0;
char *pghost, *pgport, *pgoptions, *pgtty, *dbName, *login, *pwd, *result;
char *tablename = "files";
char *valueOne = "BlahCompatible";

PGconn *conn;
PGresult *res;
ExecStatusType status;

pghost = NULL; /* host name of the backend server */
pgport = NULL; /* port of the backend server */
pgoptions = NULL; /* special options to start up the backend server */
pgtty = NULL; /* debugging tty for the backend server */
dbName = "void"; /* change this to the name of your test * database */
login = "void";
pwd = NULL; /* no pwd for now */

conn = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName, login,
pwd); /* make a connection to the database */

if (PQstatus(conn) == CONNECTION_BAD){ /* check to see that the backend
connection was successfully made */
fprintf(stderr, "Connection to database '%s' failed.\n", dbName);
fprintf(stderr, "%s", PQerrorMessage(conn));
exit_nicely(conn);
}

//res = PQmakeEmptyPGresult(conn, status);
//PQclear(res);

if ((DBinsertCmd(tablename, valueOne, conn, res)) == -1)
fprintf(stderr,"DBinsertCmd exited with -1\n");
PQclear(res);

res = PQexec(conn, "SELECT * FROM files");
while (PQresultStatus(res) == PGRES_TUPLES_OK && n < i){
result = PQgetvalue(res, n, 0);
n++;
fprintf(stdout,"resultaat: %s\n",result);
}
PQclear(res); /* PQclear(res) should PQclear PGresult whenever it is no
longer needed to avoid memory leaks */

PQfinish(conn); /* close the connection to the database and cleanup */
return 0; /* Though PQfinish(conn1) has called exit(1) */
}

int DBinsertCmd(char *tablename, char *valueOne, PGconn *conn, PGresult
*res)
{
char finalCmd[512];

if ((snprintf(finalCmd, 511, "INSERT INTO %s VALUES ('%s')", tablename,
valueOne)) == -1){
fprintf(stderr,"DBinsertCmd: WARNING! string \"%s\" was longer then
allowed, this should not have happened",finalCmd);
return -1;
}
fprintf(stdout,"%s\n",finalCmd);

res = PQexec(conn, finalCmd);
if (PQresultStatus(res) != PGRES_COMMAND_OK){
fprintf(stderr, "INSERT command failed: error returned by DB is:
%s\n",PQresStatus(PQresultStatus(res)));
return -1;
}
return 1;
}

/* CODE END */

Attachment Content-Type Size
pqtest.c text/plain 2.4 KB

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Hugo Jonker 2002-07-08 15:29:14 Insert aborted, but Sequence increased
Previous Message Andre Schroeter 2002-07-08 14:40:08 dump/restore bug