Bug #91106 NullReferenceException in Finalize crashes applications
Submitted: 1 Jun 2018 17:07 Modified: 4 Jun 2018 7:40
Reporter: Gregory Fishbein Email Updates:
Status: Duplicate Impact on me:
None 
Category:Connector / NET Severity:S1 (Critical)
Version:6.9.11 OS:Windows
Assigned to: CPU Architecture:Any

[1 Jun 2018 17:07] Gregory Fishbein
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.
[2 Jun 2018 6:17] Bradley Grainger
The call stack appears to be the same as the one in bug #90845 (although that is from an explicit call to Dispose).

It may also be the same underlying issue as bug #89159.
[4 Jun 2018 7:40] Chiranjeevi Battula
Hello Gregory Fishbein,

Thank you for the bug report.
This is most likely duplicate of Bug #90845, please see Bug #90845

Thanks,
Chiranjeevi.