From: "Paul 'Shag' Walmsley" Date: Thu, 11 Jul 1996 00:38:23 -0500 (CDT) Subject: Re: [PG95]: Backend process has died unexpectedly... On Wed, 10 Jul 1996, Marc G. Fournier wrote: > On Tue, 9 Jul 1996, Vadim B. Mikheev wrote: > > > Marc G. Fournier wrote: > > > > > > Hi... > > > > > > Well, this is getting slightly annoying: > > > > > > NOTICE:I have been signalled by the postmaster. > > > NOTICE:Some backend process has died unexpectedly and possibly > > > NOTICE:corrupted shared memory. The current transaction was > > > NOTICE:aborted, and I am going to exit. Please resend the > > > NOTICE:last query. -- The postgres backend > > > > But what SQL-request leads to crash ? > > .... > (gdb) up > #1 0x1b9d4 in get_dbrec (conn=0x38bb0, > qrystr=0xefffedd0 "select * from radacct where uniq_id='070003AC' and port='5';") at get_dbrec.c:12 > 12 if(!res || (PQntuples(res) == 0)) { > (gdb) list > 7 dblist *head, *across, *down; > 8 PGresult* res; > 9 int fieldno, row = 0; > 10 > 11 res = PQexec(conn, qrystr); > 12 if(!res || (PQntuples(res) == 0)) { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > 13 PQclear(res); > 14 return NULL; > 15 } As you noted earlier, this isn't a backend problem. Marc, in your situation, if res is null, this is guaranteed to break, since POSTGRES95 1.01pl2's PGntuples() doesn't check that res is non-null before dereferencing it. One way to fix this problem for your code would be to rewrite your code as the following: if (res) { if (PQntuples(res)==0) { PQclear(res); return NULL; } } else return NULL; However, I am of the opinion that libpq should never dump core, so I've hacked together a patch to prevent libpq from dereferencing the connection and result pointers if they're null. This patch is included at the end of this message. - - Paul "Shag" Walmsley "Knowing is not enough." -- Hal Hartley, "Surviving Desire" - -----------[ cut here ]--------------------------------------------- *** src/libpq/fe-exec.c Thu Jul 11 00:01:25 1996 - --- src/libpq/fe-exec.c.new Thu Jul 11 00:00:17 1996 *************** *** 358,369 **** char cmdStatus[MAX_MESSAGE_LEN]; char pname[MAX_MESSAGE_LEN]; /* portal name */ PGnotify *newNotify; ! FILE *Pfin = conn->Pfin; ! FILE *Pfout = conn->Pfout; ! FILE* Pfdebug = conn->Pfdebug; pname[0]='\0'; /*clear the error string */ conn->errorMessage[0] = '\0'; - --- 358,377 ---- char cmdStatus[MAX_MESSAGE_LEN]; char pname[MAX_MESSAGE_LEN]; /* portal name */ PGnotify *newNotify; ! FILE *Pfin, *Pfout, *Pfdebug; pname[0]='\0'; + if (!conn) return NULL; + if (!query) { + sprintf(conn->errorMessage, "PQexec() -- query pointer is null."); + return NULL; + } + + Pfin = conn->Pfin; + Pfout = conn->Pfout; + Pfdebug = conn->Pfdebug; + /*clear the error string */ conn->errorMessage[0] = '\0'; *************** *** 500,505 **** - --- 508,516 ---- PQnotifies(PGconn *conn) { Dlelem *e; + + if (!conn) return NULL; + if (conn->status != CONNECTION_OK) return NULL; /* RemHead returns NULL if list is empy */ *************** *** 531,536 **** - --- 542,549 ---- PQgetline(PGconn *conn, char *s, int maxlen) { int c = '\0'; + + if (!conn) return EOF; if (!conn->Pfin || !s || maxlen <= 1) return(EOF); *************** *** 561,567 **** void PQputline(PGconn *conn, char *s) { ! if (conn->Pfout) { (void) fputs(s, conn->Pfout); fflush(conn->Pfout); } - --- 574,580 ---- void PQputline(PGconn *conn, char *s) { ! if (conn && (conn->Pfout)) { (void) fputs(s, conn->Pfout); fflush(conn->Pfout); } *************** *** 580,587 **** PQendcopy(PGconn *conn) { char id; ! FILE *Pfin = conn->Pfin; ! FILE* Pfdebug = conn->Pfdebug; if ( (id = pqGetc(Pfin,Pfdebug)) > 0) return(0); - --- 593,604 ---- PQendcopy(PGconn *conn) { char id; ! FILE *Pfin, *Pfdebug; ! ! if (!conn) return NULL; ! ! Pfin = conn->Pfin; ! Pfdebug = conn->Pfdebug; if ( (id = pqGetc(Pfin,Pfdebug)) > 0) return(0); *************** *** 836,847 **** PQArgBlock *args, int nargs) { ! FILE *Pfin = conn->Pfin; ! FILE *Pfout = conn->Pfout; ! FILE* Pfdebug = conn->Pfdebug; int id; int i; /* clear the error string */ conn->errorMessage[0] = '\0'; - --- 853,868 ---- PQArgBlock *args, int nargs) { ! FILE *Pfin, *Pfout, *Pfdebug; int id; int i; + if (!conn) return NULL; + + Pfin = conn->Pfin; + Pfout = conn->Pfout; + Pfdebug = conn->Pfdebug; + /* clear the error string */ conn->errorMessage[0] = '\0'; *************** *** 916,921 **** - --- 937,947 ---- ExecStatusType PQresultStatus(PGresult* res) { + if (!res) { + fprintf(stderr, "PQresultStatus() -- pointer to PQresult is null"); + return NULL; + } + return res->resultStatus; } *************** *** 922,927 **** - --- 948,958 ---- int PQntuples(PGresult *res) { + if (!res) { + fprintf(stderr, "PQntuples() -- pointer to PQresult is null"); + return NULL; + } + return res->ntups; } *************** *** 928,933 **** - --- 959,969 ---- int PQnfields(PGresult *res) { + if (!res) { + fprintf(stderr, "PQnfields() -- pointer to PQresult is null"); + return NULL; + } + return res->numAttributes; } *************** *** 937,942 **** - --- 973,984 ---- char* PQfname(PGresult *res, int field_num) { + + if (!res) { + fprintf(stderr, "PQfname() -- pointer to PQresult is null"); + return NULL; + } + if (field_num > (res->numAttributes - 1)) { fprintf(stderr, "PQfname: ERROR! name of field %d(of %d) is not available", *************** *** 957,962 **** - --- 999,1009 ---- { int i; + if (!res) { + fprintf(stderr, "PQfnumber() -- pointer to PQresult is null"); + return -1; + } + if (field_name == NULL || field_name[0] == '\0' || res->attDescs == NULL) *************** *** 973,978 **** - --- 1020,1030 ---- Oid PQftype(PGresult *res, int field_num) { + if (!res) { + fprintf(stderr, "PQftype() -- pointer to PQresult is null"); + return InvalidOid; + } + if (field_num > (res->numAttributes - 1)) { fprintf(stderr, "PQftype: ERROR! type of field %d(of %d) is not available", *************** *** 987,992 **** - --- 1039,1049 ---- int2 PQfsize(PGresult *res, int field_num) { + if (!res) { + fprintf(stderr, "PQfsize() -- pointer to PQresult is null"); + return NULL; + } + if (field_num > (res->numAttributes - 1)) { fprintf(stderr, "PQfsize: ERROR! size of field %d(of %d) is not available", *************** *** 999,1004 **** - --- 1056,1066 ---- } char* PQcmdStatus(PGresult *res) { + if (!res) { + fprintf(stderr, "PQcmdStatus() -- pointer to PQresult is null"); + return NULL; + } + return res->cmdStatus; } *************** *** 1008,1013 **** - --- 1070,1080 ---- if not, return "" */ char* PQoidStatus(PGresult *res) { + if (!res) { + fprintf(stderr, "PQoidStatus() -- pointer to PQresult is null"); + return NULL; + } + if (!res->cmdStatus) return ""; *************** *** 1031,1036 **** - --- 1098,1108 ---- char* PQgetvalue(PGresult *res, int tup_num, int field_num) { + if (!res) { + fprintf(stderr, "PQgetvalue() -- pointer to PQresult is null"); + return NULL; + } + if (tup_num > (res->ntups - 1) || field_num > (res->numAttributes - 1)) { fprintf(stderr, *************** *** 1050,1055 **** - --- 1122,1132 ---- int PQgetlength(PGresult *res, int tup_num, int field_num) { + if (!res) { + fprintf(stderr, "PQgetlength() -- pointer to PQresult is null"); + return NULL; + } + if (tup_num > (res->ntups - 1 )|| field_num > (res->numAttributes - 1)) { fprintf(stderr, - ---------[ cut here ]--------------------------------------------------