Please help solve various memory corruption failures

Поиск
Список
Период
Сортировка
От Tsunakawa, Takayuki
Тема Please help solve various memory corruption failures
Дата
Msg-id 0A3221C70F24FB45833433255569204D1F4BA69A@G01JPEXMBYT05
обсуждение исходный текст
Список pgsql-odbc
Hello,

I've been encountering various failures leading to application crash.  They all seem to be caused by some memory
corruptionbugs.  I tried to figure out the fix, but I couldn't.  I would really appreciate your help! 

I'm using the latest release psqlodbc-09.03.0400 on Windows.  The application is multi-threaded 32-bit program.  The
threadsare independent workers, each of which uses ADO to perform simple data access: 

1. Open a database connection.
2. Execute a INSERT or SELECT statement.
3. Close a database connection.


I'll show various phenomena.


(1) Memory access violation (0xC0000005) #1
A simple SELECT statement which retrieves one row with a few columns crashed.

>    psqlodbc35w.dll!_SC_execute()  + 0x777 bytes    C
     psqlodbc35w.dll!_decideHowToPrepare()  + 0x5f2 bytes    C
     psqlodbc35w.dll!_PGAPI_Execute@8()  + 0x48a bytes    C
     psqlodbc35w.dll!_PGAPI_ExecDirect@16()  + 0x12d bytes    C
     psqlodbc35w.dll!_SQLExecDirectW@12()  + 0xaf bytes    C
     odbc32.dll!_SQLExecute@4()  - 0x2c1fe bytes
     odbc32.dll!_SQLExecDirectW@12()  + 0x7e bytes
     msdasql.dll!CImpICommandText::ExecuteHelper()  + 0x14f bytes
     msdasql.dll!CImpICommandText::Execute()  + 0xde8 bytes
     msado15.dll!CConnection::Execute()  + 0x96 bytes
     msado15.dll!_ExecuteAsync()  - 0x1e00b bytes
     msado15.dll!ExecuteAsync()  + 0x25 bytes
     msado15.dll!CQuery::Execute()  + 0x7d5 bytes
     msado15.dll!CCommand::_Execute()  + 0xe1 bytes
     msado15.dll!CRecordset::_Open()  + 0x155 bytes
     msado15.dll!CRecordset::Open()  + 0x2ea bytes
... the rest is our application

The crash point is statement.c, line 2191:

2188            /* see if the query did return any result columns */
2189            for (tres = res, numcols = 0; !numcols && tres; tres = tres->next)
2190            {
2191                numcols = QR_NumResultCols(tres);
2192            }

The value of tres->fields is bogus: it points to a non-existent memory area.  Also, tres->conn was NULL, which may be
bad. The remaining members of tres appears not-bad -- which seemed to be the state just initialized with
QR_Constructor().

According to WinDbg, the area pointed by tres is already freed.  That is, SC_execute() accessed an already freed area.
Isthere any bug in CC_send_query_append() or other functions called therein? 


(2) Stack overflow due to infinite recursive function calls
Is ConnectionClass broken?

>    psqlodbc35w.dll!_chkstk()  行 99    Asm
     psqlodbc35w.dll!_CC_send_query_append()  + 0xa バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0x1435 バイト    C
     psqlodbc35w.dll!_CC_discard_marked_objects()  + 0x94 バイト    C
     psqlodbc35w.dll!_CC_on_abort_partial()  + 0x30 バイト    C
     psqlodbc35w.dll!_EatReadyForQuery()  + 0x70 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0xce4 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0x1435 バイト    C
     psqlodbc35w.dll!_CC_discard_marked_objects()  + 0x94 バイト    C
     psqlodbc35w.dll!_CC_on_abort_partial()  + 0x30 バイト    C
     psqlodbc35w.dll!_EatReadyForQuery()  + 0x70 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0xce4 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0x1435 バイト    C
     psqlodbc35w.dll!_CC_discard_marked_objects()  + 0x94 バイト    C
...
     psqlodbc35w.dll!_CC_send_query_append()  + 0xce4 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0x1435 バイト    C
     psqlodbc35w.dll!_CC_discard_marked_objects()  + 0x94 バイト    C
     psqlodbc35w.dll!_CC_on_abort_partial()  + 0x30 バイト    C
     psqlodbc35w.dll!_EatReadyForQuery()  + 0x70 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0xce4 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0x1435 バイト    C
     psqlodbc35w.dll!_CC_discard_marked_objects()  + 0x94 バイト    C
     psqlodbc35w.dll!_CC_on_abort_partial()  + 0x30 バイト    C
     psqlodbc35w.dll!_EatReadyForQuery()  + 0x70 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0xce4 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0x1435 バイト    C
     psqlodbc35w.dll!_CC_discard_marked_objects()  + 0x94 バイト    C
     psqlodbc35w.dll!_CC_on_abort_partial()  + 0x30 バイト    C
     psqlodbc35w.dll!_EatReadyForQuery()  + 0x70 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0xce4 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0x1435 バイト    C
     psqlodbc35w.dll!_CC_discard_marked_objects()  + 0x94 バイト    C
     psqlodbc35w.dll!_CC_on_abort_partial()  + 0x30 バイト    C
     psqlodbc35w.dll!_EatReadyForQuery()  + 0x70 バイト    C
     psqlodbc35w.dll!_CC_send_query_append()  + 0xce4 バイト    C
     psqlodbc35w.dll!_SC_execute()  + 0x522 バイト    C
     psqlodbc35w.dll!_decideHowToPrepare()  + 0x5f2 バイト    C
     psqlodbc35w.dll!_PGAPI_Execute@8()  + 0x48a バイト    C
     psqlodbc35w.dll!_PGAPI_ExecDirect@16()  + 0x12d バイト    C
     psqlodbc35w.dll!_SQLExecDirectW@12()  + 0xaf バイト    C
     odbc32.dll!SQLExecDirectCover()  + 0xf0 バイト
     odbc32.dll!SQLExecDirectW()  + 0x9c バイト
     msdasql.dll!CImpICommandText::ExecuteHelper()  + 0x141 バイト
     msdasql.dll!CImpICommandText::Execute()  + 0xf02 バイト
     msado15.dll!CConnection::Execute()  + 0xcb バイト
     msado15.dll!_ExecuteAsync()  + 0x20b バイト
     msado15.dll!CQuery::Execute()  + 0x76c バイト
     msado15.dll!CCommand::_Execute()  + 0x141 バイト
     msado15.dll!CRecordset::_Open()  + 0x19a バイト
     msado15.dll!CRecordset::Open()  + 0x539 バイト
... the rest is our application


(3) Connection establishment failed(?) Describe failed(?)
I used gflags.exe to enable pageheap on the application.  Then it revealed the following failure:

STACK_TEXT:
34fad334 777b8d28 00000000 00000000 563fa7c8 ntdll!RtlpWaitOnCriticalSection+0xbd
34fad35c 73b6b2e1 563fb204 73a70233 563fa7c8 ntdll!RtlEnterCriticalSection+0x150
34fad374 73b6d1b8 563fb204 00000000 73a70233 psqlodbc35w!CC_cleanup+0x31
34fad38c 73b6d510 563fa7c8 00000000 34fad41c psqlodbc35w!CC_Destructor+0x28
34fad39c 73b6d7e0 00000001 08c37fd8 08c37fe4 psqlodbc35w!PGAPI_FreeConnect+0x260
34fad3ac 73bbbd85 08c37fd8 08e0cf5c 56394d28 psqlodbc35w!PGAPI_AllocConnect+0x30
34fad3c0 73c70570 00000002 08c37fd8 08e0cf5c psqlodbc35w!SQLAllocHandle+0x55
34fad41c 73c6fd18 05517c00 56394d28 00000000 odbc32!GetInfoForConnection+0x899
34fad440 73c7b4b2 56394d28 00000000 05517c00 odbc32!SQLInternalDriverConnectW+0x15
34fadc0c 73d20466 56394d28 00000000 1fa30f00 odbc32!SQLDriverConnectW+0x775
34fadc80 73d0f987 20506b80 00000000 1fa30f00 msdasql!CODBCHandle::OHDriverConnect+0xc6
34fadca0 73d1318f 00000000 1fa30f00 0000007f msdasql!CHdbcNode::DriverConnect+0x27
34fadcf8 741062a3 20506b80 71a9e4ac 7d173534 msdasql!CImpIDBInitialize::Initialize+0x31f
34fadd2c 7410691f 36e16f48 71a9e4e0 379e4f64 oledb32!CDBInitialize::DoInitialize+0x4c
34fadd60 740fc18e 7d173534 71a9e79c 087d1fcc oledb32!CDBInitialize::Initialize+0xc7
34fade1c 73dd967b 0890cf64 34fadecc 34fadef0 oledb32!CDCMPool::CreateResource+0x49d
34fade5c 73ddb09b 087d1fcc 34fadecc 34fadef0 comsvcs!CHolder::SafeDispenserDriver::CreateResource+0x25
34fadeac 740fd350 00000000 34fadecc 34fadef0 comsvcs!CHolder::AllocResource+0x301
34fadef8 7410817c 09782b78 379e4f58 08912fdc oledb32!CDCMPool::DrawResource+0x1eb
34fadf68 740fd06b 09782b78 379e4f58 00000017 oledb32!CDCMPoolManager::DrawResource+0x51c
34fadffc 74201c5a 379e4f68 71b63be6 48944f90 oledb32!CDPO::Initialize+0x2c9
34fae11c 74201b5f 48944f90 00000000 48944d18 msado15!_ConnectAsync+0x61c
34fae130 74200dc2 48944f90 48944d18 4e55cff0 msado15!ConnectAsync+0x83
34fae330 00401618 00944d18 00000000 008d3fe4 msado15!CConnection::Open+0x111d
... the rest is our application


(4)
pageheap revealed another failure:

STACK_TEXT:
294e7c0c 73aeaf7d 00000000 00000000 00000000 msvcr100!_invoke_watson+0x12
294e7c28 73aeaf8a 00000000 00000000 00000000 msvcr100!_invalid_parameter+0x2c
294e7c40 73a9a1ae 29162a40 73b14ae8 73b148c0 msvcr100!_invalid_parameter_noinfo+0xc
294e7c68 73a80c4b 73b16360 00000000 00000000 msvcr100!strtod+0x50
294e7c84 73a80c61 00000000 00000000 0000000a msvcr100!strtol+0x26
294e7c98 73b9b296 00000000 00000bd0 00000071 msvcr100!atol+0x11
294e7cb8 73b9cf90 796410c8 29162a40 29162a40 psqlodbc35w!FI_scale+0x6b6
294e7cf4 73b9d446 4f550db8 5485efe0 4f550db8 psqlodbc35w!SC_set_SS_columnkey+0x6e0
294e7d18 73ba68d6 73bd5bb8 4abc8588 4f550db8 psqlodbc35w!getCOLIfromTI+0x2d6
294e7d44 73ba6dc9 00000001 00000000 73bd5bb8 psqlodbc35w!PGAPI_RowCount+0x246
294e7e9c 73bbf27c 4f550db8 00000001 54834fe0 psqlodbc35w!PGAPI_DescribeCol+0x269
294e7ed8 73c6f2d0 4f550fe8 00000001 00000000 psqlodbc35w!SQLDescribeColW+0x8c
4f550db8 5072af50 5072af50 08dc6d18 00000000 odbc32!ToAnsi_SQLColAttributes+0x542




(5) NULL dereference

>    psqlodbc35w.dll!_SC_clear_error()  + 0x3b2 バイト    C
     psqlodbc35w.dll!_PGAPI_StmtError@32()  + 0x10 バイト    C
     psqlodbc35w.dll!_PGAPI_GetDiagField@28()  + 0x460 バイト    C
     psqlodbc35w.dll!_SQLGetDiagFieldW@28()  + 0xc1 バイト    C
     odbc32.dll!_PostErrorArg@12()  + 0x6db バイト
     odbc32.dll!_SearchStatusCode@8()  + 0x80 バイト
     odbc32.dll!_IsStmtPositioned@4()  + 0x14 バイト
     odbc32.dll!_SQLExecute@4()  - 0x1c01c バイト
     odbc32.dll!_SQLExecDirectW@12()  + 0x7e バイト
     msdasql.dll!CImpICommandText::ExecuteHelper()  + 0x14f バイト
     msdasql.dll!CImpICommandText::Execute()  + 0xde8 バイト
     msado15.dll!CConnection::Execute()  + 0x96 バイト
     msado15.dll!_ExecuteAsync()  - 0x1dcbb バイト
     msado15.dll!ExecuteAsync()  + 0x25 バイト
     msado15.dll!CQuery::Execute()  + 0x7d2 バイト
     msado15.dll!CCommand::_Execute()  + 0xe1 バイト
     msado15.dll!CRecordset::_Open()  + 0x155 バイト
     msado15.dll!CRecordset::Open()  + 0x301 バイト

The following line in SC_create_errorinfo() (statement.c) caused the crash.  pgerror was NULL.  That means that
malloc()in ER_Constructor() failed.  NULL check is necessary somewhere. 

            strcpy(pgerror->sqlstate, EN_is_odbc3(env) ?
                   Statement_sqlstate[errornum].ver3str :
                   Statement_sqlstate[errornum].ver2str);


(6) Abrupt socket close
Throughout the test, these messages are frequently output in the PostgreSQL server log file:

LOG:  could not receive data from client: No connection could be made because the target machine actively refused it.
LOG:  unexpected EOF on client connection

The application is coded to perform clean database connection termination.  So, psqlODBC seems to close the socket
abruptly. As its evidence, recv() and send() in psqlODBC frequently failed with WSAENOTSOCK (10038).  I suspect
ConnectionClassis corrupted and its socket member is broken. 


Regards
Takayuki Tsunakawa




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

Предыдущее
От: Haribabu Kommi
Дата:
Сообщение: Re: Error in calling a function with protocol 7.4
Следующее
От: "Venkata Mahesh. Putta"
Дата:
Сообщение: psqlODBC 08.03- Supportability