BUG #5697: Infinite loop inside PQexecStart function

From: "Boris" <admin(at)nyc(dot)yamaha(dot)com>
To: pgsql-bugs(at)postgresql(dot)org
Subject: BUG #5697: Infinite loop inside PQexecStart function
Date: 2010-10-07 14:10:18
Message-ID: 201010071410.o97EAI5j093356@wwwmaster.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs


The following bug has been logged online:

Bug reference: 5697
Logged by: Boris
Email address: admin(at)nyc(dot)yamaha(dot)com
PostgreSQL version: 8.3.5
Operating system: Linux RH ES5
Description: Infinite loop inside PQexecStart function
Details:

The infinite loop in this case occurs inside the PQexecStart() function in
pgsql driver. The following insert corresponds to the actual infinite loop.
The are several conditions that are checked "(result = PQgetResult(conn)) !=
NULL" and "result->resultStatus == PGRES_COPY_IN || result->resultStatus ==
PGRES_COPY_OUT || conn->status == CONNECTION_BAD" as an exit point.
---------------------------------------------------------
ASM code
0x0042bca5 in PQexecStart () from /usr/local/pgsql/lib/libpq.so.5
17 0x0042bca5 <PQexecStart+37>: cmp $0x3,%esi
18 0x0042bca8 <PQexecStart+40>: je 0x42bd00 <PQexecStart+128>
19 0x0042bcaa <PQexecStart+42>: cmpl $0x1,0x44(%edi)
20 0x0042bcae <PQexecStart+46>: je 0x42bcf0 <PQexecStart+112>
21 0x0042bcb0 <PQexecStart+48>: mov %edi,(%esp)
22 0x0042bcb3 <PQexecStart+51>: call 0x424fa0 <PQgetResult(at)plt>
23 0x0042bcb8 <PQexecStart+56>: test %eax,%eax
24 0x0042bcba <PQexecStart+58>: je 0x42bd13 <PQexecStart+147>
25 0x0042bcbc <PQexecStart+60>: mov 0x1c(%eax),%esi
26 0x0042bcbf <PQexecStart+63>: mov %eax,(%esp)
27 0x0042bcc2 <PQexecStart+66>: call 0x4255d0 <PQclear(at)plt>
28 0x0042bcc7 <PQexecStart+71>: cmp $0x4,%esi
29 0x0042bcca <PQexecStart+74>: jne 0x42bca5 <PQexecStart+37>

---------------------------------------------------------
The C-code corresponding to this part (short version):
while ((result = PQgetResult(conn)) != NULL){
ExecStatusType resultStatus = result->resultStatus;
PQclear(result); /* only need its status */
/* check for loss of connection, too */
if (result->resultStatus == PGRES_COPY_IN ||
result->resultStatus == PGRES_COPY_OUT ||
conn->status == CONNECTION_BAD)
break;
}
return true;
---------------------------------------------------------
These are the values mapped to the corresponding constants:
PGRES_EMPTY_QUERY = 0
PGRES_COMMAND_OK = 1
PGRES_TUPLES_OK = 2
PGRES_COPY_OUT = 3
PGRES_COPY_IN = 4
PGRES_BAD_RESPONSE = 5
PGRES_NONFATAL_ERROR = 6
PGRES_FATAL_ERROR = 7

Condition exit point is evaluated against 3 constants PGRES_COPY_IN,
PGRES_COPY_OUT, CONNECTION_BAD. Since the connection to the database is in a
"GOOD" state the only constants that are evaluated are PGRES_COPY_IN and
PGRES_COPY_OUT, but according to the debugger trace the value those are
compared against is 7, e.g. PGRES_FATAL_ERROR which has no condition and
thus the process runs forever. Please see the following insert with detailed
output of the registers.
---------------------------------------------------------
0x0042bcc7 in PQexecStart () from /usr/local/pgsql/lib/libpq.so.5
1: x/i $pc 0x42bcc7 <PQexecStart+71>: cmp $0x4,%esi
(gdb) i r
eax 0x99 153
ecx 0x1 1
edx 0x98 152
ebx 0x43a330 4432688
esp 0xbfe506d0 0xbfe506d0
ebp 0xbfe506e8 0xbfe506e8
esi 0x7 7
edi 0x98c5bb4 160193460
eip 0x42bcc7 0x42bcc7 <PQexecStart+71>
eflags 0x286 [ PF SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Dave Page 2010-10-07 14:10:52 Re: BUG #5696: cannot upgrade to 9.0.1
Previous Message Dave Page 2010-10-07 13:30:31 Re: BUG #5696: cannot upgrade to 9.0.1