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 ()
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)

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

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report for Bug 35376 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:

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?