Description:
The MySqlDataReader can throw nullreference exceptions in its dispose method that is called from the Finalize. This will crash your application as the exception is unhandled. I seem to either get an error here:
System.NullReferenceException: Object reference not set to an instance of an object.
at MySql.Data.MySqlClient.MySqlConnection.set_Reader(MySqlDataReader value)
at MySql.Data.MySqlClient.MySqlDataReader.Close()
at MySql.Data.MySqlClient.MySqlDataReader.Dispose(Boolean disposing)
at MySql.Data.MySqlClient.MySqlDataReader.Finalize()
or here:
System.NullReferenceException: Object reference not set to an instance of an object.
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
at MySql.Data.MySqlClient.MySqlDataReader.Close()
at MySql.Data.MySqlClient.MySqlDataReader.Dispose(Boolean disposing)
at MySql.Data.MySqlClient.MySqlDataReader.Finalize()
I think the second one happens when the query is in the process of sending data back and it has a timeout.
How to repeat:
public void CrashTestFunc()
{
var provider = System.Data.Common.DbProviderFactories.GetFactory("MySql.Data.MySqlClient");
try
{
using (var conn = provider.CreateConnection())
{
conn.ConnectionString = @"<YOUR CONNECTION STRING>";
conn.Open();
using (var adapter = provider.CreateDataAdapter())
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "<YOUR LONG RUNNING QUERY>";
cmd.CommandTimeout = 1;
adapter.SelectCommand = cmd;
var dt = new DataTable();
adapter.Fill(dt);
}
}
}
}catch(Exception e)
{
System.Console.WriteLine("catching timeout exception");
}
}
public in Main()
{
System.Threading.Tasks.Task.Factory.StartNew(CrashTestFunc);
System.Threading.Tasks.Task.Factory.StartNew(CrashTestFunc);
System.Threading.Tasks.Task.Factory.StartNew(CrashTestFunc);
System.Threading.Thread.Sleep(10000);
}
Suggested fix:
The MySqlDataReader that is used underneath by the command and dataadapter should have been disposed of when the commmand and dataadapter were disposed. I think that is probably a bug.
If it wasn't disposed of correctly then, the finalize method should not assume the driver and driver.stream are not null. or you can catch these exceptions in dispose and not crash the program.
Description: The MySqlDataReader can throw nullreference exceptions in its dispose method that is called from the Finalize. This will crash your application as the exception is unhandled. I seem to either get an error here: System.NullReferenceException: Object reference not set to an instance of an object. at MySql.Data.MySqlClient.MySqlConnection.set_Reader(MySqlDataReader value) at MySql.Data.MySqlClient.MySqlDataReader.Close() at MySql.Data.MySqlClient.MySqlDataReader.Dispose(Boolean disposing) at MySql.Data.MySqlClient.MySqlDataReader.Finalize() or here: System.NullReferenceException: Object reference not set to an instance of an object. at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId) at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force) at MySql.Data.MySqlClient.MySqlDataReader.NextResult() at MySql.Data.MySqlClient.MySqlDataReader.Close() at MySql.Data.MySqlClient.MySqlDataReader.Dispose(Boolean disposing) at MySql.Data.MySqlClient.MySqlDataReader.Finalize() I think the second one happens when the query is in the process of sending data back and it has a timeout. How to repeat: public void CrashTestFunc() { var provider = System.Data.Common.DbProviderFactories.GetFactory("MySql.Data.MySqlClient"); try { using (var conn = provider.CreateConnection()) { conn.ConnectionString = @"<YOUR CONNECTION STRING>"; conn.Open(); using (var adapter = provider.CreateDataAdapter()) { using (var cmd = conn.CreateCommand()) { cmd.CommandText = "<YOUR LONG RUNNING QUERY>"; cmd.CommandTimeout = 1; adapter.SelectCommand = cmd; var dt = new DataTable(); adapter.Fill(dt); } } } }catch(Exception e) { System.Console.WriteLine("catching timeout exception"); } } public in Main() { System.Threading.Tasks.Task.Factory.StartNew(CrashTestFunc); System.Threading.Tasks.Task.Factory.StartNew(CrashTestFunc); System.Threading.Tasks.Task.Factory.StartNew(CrashTestFunc); System.Threading.Thread.Sleep(10000); } Suggested fix: The MySqlDataReader that is used underneath by the command and dataadapter should have been disposed of when the commmand and dataadapter were disposed. I think that is probably a bug. If it wasn't disposed of correctly then, the finalize method should not assume the driver and driver.stream are not null. or you can catch these exceptions in dispose and not crash the program.