[unixODBC-dev] Postgres 2.2.12 CPU exhaustion bug

Oren Nechushtan oren at forescout.com
Thu May 24 13:13:13 BST 2007


Hi,
Sometimes the postgre* process consumes too much CPU, always with the
next stack ..

(gdb) where
#0  0x401bd512 in __libc_recvfrom () at __libc_recvfrom:-1
#1  0x400287e4 in recv (fd=6, buf=0x93508c8, n=4096, flags=0)
    at wrapsyscall.c:198
#2  0x402429ae in SOCK_get_next_byte () from /usr/lib/libodbcpsql.so
#3  0x4022a259 in CC_send_query () from /usr/lib/libodbcpsql.so
#4  0x40243e68 in SC_execute () from /usr/lib/libodbcpsql.so
#5  0x4023320e in PG_SQLExecute () from /usr/lib/libodbcpsql.so
#6  0x40232ece in PG_SQLExecDirect () from /usr/lib/libodbcpsql.so
#7  0x40232f13 in SQLExecDirect () from /usr/lib/libodbcpsql.so
#8  0x40081ded in SQLExecDirect () from /usr/lib/libodbc.so.1
...

and log

read 0, global_socket_buffersize=4096
read 0, global_socket_buffersize=4096
read 0, global_socket_buffersize=4096

This probably happens when the backend dies within the block below
(without a proper exception handling.)
Here is a partial patch (same applies for other drivers; You would
probably want to alter the mylog message)

--- unixODBC-2.2.12/Drivers/PostgreSQL/connection.c.orig        Thu May
24 12:30:53 2007
+++ unixODBC-2.2.12/Drivers/PostgreSQL/connection.c             Thu May
24 12:36:24 2007
@@ -972,6 +972,16 @@

                                while( ! clear) {
                                        id = SOCK_get_char(sock);
+                                       if ((SOCK_get_errcode(sock) !=
0) || (id == EOF)) {
+                                               self->errornumber =
CONNECTION_NO_RESPONSE;
+                                               self->errormsg = "No
response from the backend";
+                                               if (res)
+
QR_Destructor(res);
+
+                                               mylog("send_query: id=%d
error=%s \n", id, self->errormsg);
+                                               CC_set_no_trans(self);
+                                               return NULL;
+                                       }
                                        switch(id) {
                                        case 'I':
                                                (void)
SOCK_get_char(sock);

Also, the sources may not compile without the next patch.

--- unixODBC-2.2.12/Drivers/Postgre7.1/convert.c.orig   Mon Sep 26
15:44:01 2005
+++ unixODBC-2.2.12/Drivers/Postgre7.1/convert.c        Thu May 24
12:45:28 2007
@@ -1568,7 +1568,7 @@
 convert_from_pgbinary(unsigned char *value, unsigned char *rgbValue,
int cbValueMax)
 {
 int o=0;
-size_t i, valen=strlen((char*)value);;
+size_t i, valen=strlen((char*)value);


        for (i = 0; i < valen && o < cbValueMax; )


Best,
Oren N.



More information about the unixODBC-dev mailing list