We recently upgraded to 1.0.80.0 from 1.0.77.0 and have found when we turn
connection pooling on we get seemingly random memory access violations that
happen in calls to UnsafeNativeMethods.sqlite3_busy_timeout ,call stack -
Open/SetTimeout (line 259 of SQLite3.cs).

After compiling SQLite debug what I have seen is that if the
SQLiteConnection object was disposed of by the garbage collector then the
object left in the pool has an invalid _sql pointer.  If the
SQLiteConnection is disposed explicitly such as at the end of a using
statement everything seems to work.

When I see the connection added to the pool the stack trace begins
somewhere in kernel, so I'm assuming that means it is the result of garbage
collection.  Then after it is added to the pool I see that the underlying
handle is released by the garbage collector.  Then the connection is
returned from the pool and boom.

connection is added to pool
+        ((System.Runtime.InteropServices.CriticalHandle)(hdl)).handle
148364464    System.IntPtr

>
System.Data.SQLite.dll!System.Data.SQLite.SQLiteConnectionPool.Add(string
fileName = "D:\\tdb\\TS7_workshops\\TS7_workshops\\1 TS6_import\\73\\RQC
exercise v6.2.tdb", System.Data.SQLite.SQLiteConnectionHandle hdl =
{System.Data.SQLite.SQLiteConnectionHandle}, int version = 1) Line 166    C#
     System.Data.SQLite.dll!System.Data.SQLite.SQLite3.Close() Line 120 +
0x24 bytes    C#
     System.Data.SQLite.dll!System.Data.SQLite.SQLite3.Dispose(bool
disposing = false) Line 95 + 0x8 bytes    C#
     System.Data.SQLite.dll!System.Data.SQLite.SQLiteBase.Finalize() Line
330 + 0xd bytes    C#
     [Frames below may be incorrect and/or missing, no symbols loaded for
mscorwks.dll]
     ntdll.dll!7718f9b9()
     KernelBase.dll!768703c8()
     kernel32.dll!7534339a()
     ntdll.dll!771a9ef2()
     ntdll.dll!771a9ec5()

underlying connection is freed
+        ((System.Runtime.InteropServices.CriticalHandle)(db)).handle
148364464    System.IntPtr

>
System.Data.SQLite.dll!System.Data.SQLite.SQLiteBase.CloseConnection(System.Data.SQLite.SQLiteConnectionHandle
db = {System.Data.SQLite.SQLiteConnectionHandle}) Line 376    C#

System.Data.SQLite.dll!System.Data.SQLite.SQLiteConnectionHandle.ReleaseHandle()
Line 1375 + 0x8 bytes    C#
     mscorlib.dll!System.Runtime.InteropServices.CriticalHandle.Cleanup() +
0x32 bytes

mscorlib.dll!System.Runtime.InteropServices.CriticalHandle.Dispose(bool
disposing) + 0x5 bytes
     mscorlib.dll!System.Runtime.InteropServices.CriticalHandle.Finalize()
+ 0x1b bytes
     [Frames below may be incorrect and/or missing, no symbols loaded for
mscorwks.dll]
     ntdll.dll!7718f9b9()
     KernelBase.dll!768703c8()
     kernel32.dll!7534339a()
     ntdll.dll!771a9ef2()
     ntdll.dll!771a9ec5()

connection is returned from the pool.
+        ((System.Runtime.InteropServices.CriticalHandle)(hdl)).handle
148364464    System.IntPtr

>
System.Data.SQLite.dll!System.Data.SQLite.SQLiteConnectionPool.Remove(string
fileName = "D:\\tdb\\TS7_workshops\\TS7_workshops\\1 TS6_import\\73\\RQC
exercise v6.2.tdb", int maxPoolSize = 100, out int version = 1) Line 82
C#
     System.Data.SQLite.dll!System.Data.SQLite.SQLite3.Open(string
strFilename = "D:\\tdb\\TS7_workshops\\TS7_workshops\\1 TS6_import\\73\\RQC
exercise v6.2.tdb", System.Data.SQLite.SQLiteConnectionFlags
connectionFlags = LogCallbackException,
System.Data.SQLite.SQLiteOpenFlagsEnum openFlags = ReadWrite | Create, int
maxPoolSize = 100, bool usePool = true) Line 225 + 0x1b bytes    C#
     System.Data.SQLite.dll!System.Data.SQLite.SQLiteConnection.Open() Line
1065 + 0x32 bytes    C#

Utilities.dll!Geocosm.Touchstone.Utilities.DatabaseConnectionFactory.GetCurrentProjectConnection()
Line 232 + 0xb bytes    C#

TSUtilities.dll!TSUtilities.clsObjBase.GetDataAdapter(System.Data.IDbConnection
connection = Nothing) Line 230 + 0x5 bytes    Basic
     TSUtilities.dll!TSUtilities.clsObjBase.SaveToDB() Line 500 + 0x12
bytes    Basic

The call to UnsafeNativeMethods.sqlite3_busy_timeout then fails with memory
access violation as the _sql pointer is no longer valid.

In the cases where everything works as it should I see a clear stack trace
back to my code where the connection is disposed of at the end of a using
when it is added to the pool.  It's when we have connections that are
disposed of as a result of garbage collection that things go wrong.

So is this intended behaviour or a bug?  I can try to come up with a test
case that reproduces this if needed.
Thanks
Greg.
FYI Windows 7 x64 but application is win32, MSVC 2008, using the .net 3.5
prebuilt SQLite for win32.
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to