BUG #5697: Infinite loop inside PQexecStart function

Поиск
Список
Период
Сортировка
От Boris
Тема BUG #5697: Infinite loop inside PQexecStart function
Дата
Msg-id 201010071410.o97EAI5j093356@wwwmaster.postgresql.org
обсуждение исходный текст
Ответы Re: BUG #5697: Infinite loop inside PQexecStart function
Список pgsql-bugs
The following bug has been logged online:

Bug reference:      5697
Logged by:          Boris
Email address:      admin@nyc.yamaha.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@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@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

В списке pgsql-bugs по дате отправления:

Предыдущее
От: Dave Page
Дата:
Сообщение: Re: BUG #5696: cannot upgrade to 9.0.1
Следующее
От: Tom Lane
Дата:
Сообщение: Re: BUG #5697: Infinite loop inside PQexecStart function