Bug 35376 - OdbcDataReader:GetValue stuck in loop - System.Data.Odbc.libodbc:SQLGetDataGetData, System.Data.Odbc.OdbcColumn:get_SqlCType
Summary: OdbcDataReader:GetValue stuck in loop - System.Data.Odbc.libodbc:SQLGetDataGe...
Status: NEW
Alias: None
Product: Runtime
Classification: Mono
Component: General (show other bugs)
Version: 4.0.0
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
Depends on:
Reported: 2015-10-29 16:35 UTC by TheOldMan
Modified: 2015-10-29 16:35 UTC (History)
2 users (show)

See Also:
Is this bug a regression?: ---
Last known good build:


Description TheOldMan 2015-10-29 16:35:31 UTC
Simple program (abridged):

         string sql = "select col2,col1 from moose order by col1";
         dbcmd.CommandText = sql;
         IDataReader reader = dbcmd.ExecuteReader();
         data = reader.GetValue(0).ToString();
         Console.WriteLine("Col2: " + data);
         data = reader.GetValue(1).ToString();
         Console.WriteLine("Col1: " + data);

col1 - integer, col2 - char (10). The problem is any char() column. I get this loop:

[0x7fecf47d6780: 0.15158 2] ENTER: System.Data.Odbc.OdbcDataReader:GetValue (int)(this:0x7fecf280cf20[System.Data.Odbc.OdbcDataReader odbc.exe], 1, )
[0x7fecf47d6780: 0.15159 3] ENTER: System.Data.Odbc.OdbcDataReader:get_IsClosed ()(this:0x7fecf280cf20[System.Data.Odbc.OdbcDataReader odbc.exe], )
[0x7fecf47d6780: 0.15159 3] LEAVE: System.Data.Odbc.OdbcDataReader:get_IsClosed ()FALSE
[0x7fecf47d6780: 0.15159 3] ENTER: System.Data.Odbc.OdbcDataReader:GetColumn (int)(this:0x7fecf280cf20[System.Data.Odbc.OdbcDataReader odbc.exe], 1, )
[0x7fecf47d6780: 0.15160 3] LEAVE: System.Data.Odbc.OdbcDataReader:GetColumn (int)[System.Data.Odbc.OdbcColumn:0x7fecf280e468]
[0x7fecf47d6780: 0.15160 3] ENTER: (wrapper alloc) object:AllocVector (intptr,intptr)(0x1924ae8, 0xb, )
[0x7fecf47d6780: 0.15160 3] LEAVE: (wrapper alloc) object:AllocVector (intptr,intptr)[System.Byte[]:0x7fecf280e850]
[0x7fecf47d6780: 0.15161 3] ENTER: (wrapper alloc) object:AllocSmall (intptr,intptr)(0x1af7e50, 0x30, )
[0x7fecf47d6780: 0.15161 3] LEAVE: (wrapper alloc) object:AllocSmall (intptr,intptr)[System.Text.StringBuilder:0x7fecf280e880]
[0x7fecf47d6780: 0.15163 3] ENTER: (wrapper alloc) object:AllocVector (intptr,intptr)(0x1944f20, 0xb, )
[0x7fecf47d6780: 0.15163 3] LEAVE: (wrapper alloc) object:AllocVector (intptr,intptr)[System.Char[]:0x7fecf280e8b0]
[0x7fecf47d6780: 0.15164 3] ENTER: (wrapper alloc) object:AllocSmall (intptr,intptr)(0x19a1c90, 0x30, )
[0x7fecf47d6780: 0.15164 3] LEAVE: (wrapper alloc) object:AllocSmall (intptr,intptr)[System.Text.DecoderNLS:0x7fecf280e8e8]
[0x7fecf47d6780: 0.15169 3] ENTER: System.Data.Odbc.OdbcColumn:get_SqlCType ()(this:0x7fecf280e468[System.Data.Odbc.OdbcColumn odbc.exe], )
[0x7fecf47d6780: 0.15169 3] LEAVE: System.Data.Odbc.OdbcColumn:get_SqlCType ()result=1
[0x7fecf47d6780: 0.15170 3] ENTER: (wrapper managed-to-native) System.Data.Odbc.libodbc:SQLGetData (intptr,uint16,System.Data.Odbc.SQL_C_TYPE,byte[],int,int&)(0x1acf770, 2, 1, 0x7fecf280e850, 11, [BYREF:0x7fff82ddfeb8], )
[0x7fecf47d6780: 0.15171 4] ENTER: (wrapper managed-to-native) object:__icall_wrapper_mono_array_to_lparray (object)([System.Byte[]:0x7fecf280e850], )
[0x7fecf47d6780: 0.15171 4] LEAVE: (wrapper managed-to-native) object:__icall_wrapper_mono_array_to_lparray (object)result=-226432912
[0x7fecf47d6780: 0.15174 4] ENTER: (wrapper managed-to-native) object:__icall_wrapper_mono_free_lparray (object,intptr)([System.Byte[]:0x7fecf280e850], 0x7fecf280e870, )
[0x7fecf47d6780: 0.15175 4] LEAVE: (wrapper managed-to-native) object:__icall_wrapper_mono_free_lparray (object,intptr)
[0x7fecf47d6780: 0.15175 3] LEAVE: (wrapper managed-to-native) System.Data.Odbc.libodbc:SQLGetData (intptr,uint16,System.Data.Odbc.SQL_C_TYPE,byte[],int,int&)result=0
[0x7fecf47d6780: 0.15177 3] ENTER: (wrapper alloc) object:AllocString (intptr,int)(0x1924d48, 32, )
[0x7fecf47d6780: 0.15177 3] LEAVE: (wrapper alloc) object:AllocString (intptr,int)[STRING:0x7fecf280e918:]
[0x7fecf47d6780: 0.15178 3] ENTER: System.Data.Odbc.OdbcColumn:get_SqlCType ()(this:0x7fecf280e468[System.Data.Odbc.OdbcColumn odbc.exe], )
[0x7fecf47d6780: 0.15178 3] LEAVE: System.Data.Odbc.OdbcColumn:get_SqlCType ()result=1
[0x7fecf47d6780: 0.15179 3] ENTER: (wrapper managed-to-native) System.Data.Odbc.libodbc:SQLGetData (intptr,uint16,System.Data.Odbc.SQL_C_TYPE,byte[],int,int&)(0x1acf770, 2, 1, 0x7fecf280e850, 11, [BYREF:0x7fff82ddfeb8], )
[0x7fecf47d6780: 0.15179 4] ENTER: (wrapper managed-to-native) object:__icall_wrapper_mono_array_to_lparray (object)([System.Byte[]:0x7fecf280e850], )
[0x7fecf47d6780: 0.15180 4] LEAVE: (wrapper managed-to-native) object:__icall_wrapper_mono_array_to_lparray (object)result=-226432912
[0x7fecf47d6780: 0.15182 4] ENTER: (wrapper managed-to-native) object:__icall_wrapper_mono_free_lparray (object,intptr)([System.Byte[]:0x7fecf280e850], 0x7fecf280e870, )
[0x7fecf47d6780: 0.15183 4] LEAVE: (wrapper managed-to-native) object:__icall_wrapper_mono_free_lparray (object,intptr)
[0x7fecf47d6780: 0.15183 3] LEAVE: (wrapper managed-to-native) System.Data.Odbc.libodbc:SQLGetData (intptr,uint16,System.Data.Odbc.SQL_C_TYPE,byte[],int,int&)result=0

Of course this happens only when using our odbc driver + SQL processor for MicroFocus' Vision dbms; the same test works fine for other odbc driver, e.g. MySQL. Our driver works fine outside of the Mono environment, for example using unixODBC's isql, a vast array of ODBC clients (MS Excel, CrystalReports, etc...) so I know that our s/w is ok (it's been in production for almost two decades). The problem occurs on Windows and Linux so there is *something* in Mono's ODBC client that is expecting something from our driver that it is not getting. I look at the ODBC trace as well but no errors show up.

I built Mono with debug (-g) and when I run it under gdb, I get a SEGV:

Program received signal SIGSEGV, Segmentation fault.
0x000000000054739a in mono_free_lparray (array=0x7ffff60116c0, nativeArray=
    0x7ffff60116e0) at marshal.c:631
631             switch (klass->element_class->byval_arg.type) {

No surprise because klass = 0 but when I put a bp at 

klass = array->obj.vtable->klass;

and look at both klass and array->obj.vtable->klass, they both have the same value, step and now klass = 0! Weird. The SEGV gets handled but this ends up going all over the place.

I compared the mono --trace output between our driver and MySQL's. SQLGetData (MySQL) is asking for SQL_C_WCHAR whereas SQLGetData (our driver) is asking for SQL_C_CHAR. Perhaps this is the problem but I'm having a tough time digging through the Mono ODBC client stuff.

I'm going to try DB2 next. Does any of this ring a bell and is there any deeper tracing or debugging that I can set for Mono?

Note You need to log in before you can comment on or make changes to this bug.