mysql-net / MySqlConnector

MySQL Connector for .NET
https://mysqlconnector.net
MIT License
1.39k stars 334 forks source link

System.InvalidProgramException: Common Language Runtime detected an invalid program. #1519

Open shajiltetherfi opened 5 days ago

shajiltetherfi commented 5 days ago

Software versions MySqlConnector version: 2.3.6 Server type (MySQL, MariaDB, Aurora, etc.) and version: MYSQL .NET version: >.NET6 (Optional) ORM NuGet packages and versions:

Describe the bug System.InvalidProgramException: Common Language Runtime detected an invalid program. Exception Full exception message and call stack (if applicable)

2024-10-17 13:54:41,154 [39] INFO Core.ORM.MySqlAdapter - Connection Opened:
2024-10-17 13:54:41,155 [39] INFO Core.ORM.MySqlAdapter - Start Connection Execute with: CREATE TEMPORARY TABLE TmpIn_CMM_Role_Pages_6541bc52679842279c38e65b978d250b SELECT RoleID , PageName , USER_ACCESS , ADD_ACCESS , EDIT_ACCESS , DELETE_ACCESS , EXPORT_ACCESS , LAST_CHANGED_BY , LAST_CHANGED_ON  FROM CMM_Role_Pages target LIMIT 0;:
2024-10-17 13:54:41,160 [39] ERROR Core.ORM.MySqlAdapter - Catch 2: System.InvalidProgramException: Common Language Runtime detected an invalid program.
   at MySqlConnector.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
   at MySqlConnector.MySqlCommand.ExecuteNonQuery() in /_/src/MySqlConnector/MySqlCommand.cs:line 108
   at Dapper.SqlMapper.ExecuteCommand(IDbConnection cnn, CommandDefinition& command, Action`2 paramReader) in C:\projects\dapper\Dapper\SqlMapper.cs:line 2827
   at Dapper.SqlMapper.ExecuteImpl(IDbConnection cnn, CommandDefinition& command) in C:\projects\dapper\Dapper\SqlMapper.cs:line 570
   at Core.ORM.MySqlAdapter.BulkUpsert[T](IDbConnection connection, IDbTransaction transaction, IEnumerable`1 data, String tableName, Type type, Int32 bulkCopyTimeout, Nullable`1 commandTimeout):
2024-10-17 13:54:41,161 [39] ERROR OCM.Utilities.SqlDataAccess - ExecuteBulkUpsertQuery:System.InvalidProgramException: Common Language Runtime detected an invalid program.
   at MySqlConnector.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
   at MySqlConnector.MySqlCommand.ExecuteNonQuery() in /_/src/MySqlConnector/MySqlCommand.cs:line 108
   at Dapper.SqlMapper.ExecuteCommand(IDbConnection cnn, CommandDefinition& command, Action`2 paramReader) in C:\projects\dapper\Dapper\SqlMapper.cs:line 2827
   at Dapper.SqlMapper.ExecuteImpl(IDbConnection cnn, CommandDefinition& command) in C:\projects\dapper\Dapper\SqlMapper.cs:line 570
   at Core.ORM.MySqlAdapter.BulkUpsert[T](IDbConnection connection, IDbTransaction transaction, IEnumerable`1 data, String tableName, Type type, Int32 bulkCopyTimeout, Nullable`1 commandTimeout)
   at Core.ORM.DapperExtensions.BulkUpsert[T](IDbConnection connection, IEnumerable`1 data, IDbTransaction transaction, Int32 batchSize, Int32 bulkCopyTimeout, Nullable`1 commandTimeout)
   at OCM.Utilities.SqlDataAccess.ExecuteBulkUpsertQuery[T](IEnumerable`1 obj)

Code sample

public void BulkUpsert<T>(IDbConnection connection, IDbTransaction transaction, IEnumerable<T> data, string tableName, Type type, int bulkCopyTimeout, int? commandTimeout)
{
    var allProperties = PropertiesCache.TypePropertiesCache(type);
    var keyProperties = PropertiesCache.KeyPropertiesCache(type);
    var computedProperties = PropertiesCache.ComputedPropertiesCache(type);
    var columns = PropertiesCache.GetColumnNamesCache(type);

    var allPropertiesExceptComputed = allProperties.Except(computedProperties).ToList();
    //var tempToBeInserted = $"TempInsert_{tableName}_{Guid.NewGuid().ToString("N")}".Replace(".", string.Empty);
    var tempToBeInserted = $"TmpIn_{tableName}_{Guid.NewGuid().ToString("N")}".Replace(".", string.Empty);
    tempToBeInserted = tempToBeInserted.Substring(0, Math.Min(tempToBeInserted.Length, 64));

    var allPropertiesExceptKeyAndComputed = allProperties.Except(keyProperties.Union(computedProperties)).ToList();
    var mergingProperties = PropertiesCache.MergeConditionPropertiesCache(type);

    string tempSql = $@"CREATE TEMPORARY TABLE  {tempToBeInserted} SELECT { GetColumnsStringSqlServer(allPropertiesExceptComputed, columns)} FROM {tableName} target LIMIT 0;";

    var con = new MySqlConnection(connection.ConnectionString);

    if (!con.ConnectionString.ToLower().Replace(" ", "").Contains("allowloadlocalinfile=true"))
    {
        con.ConnectionString += ";allowloadlocalinfile = true;";
    }

    var bulkCopy = new MySqlBulkCopy(con, transaction as MySqlTransaction);

    try
    {
        con.Open();
        con.Execute(tempSql, null, transaction as MySqlTransaction, commandTimeout);
        List<MySqlBulkCopyColumnMapping> colMappings = new List<MySqlBulkCopyColumnMapping>();
        int i = 0;
        foreach (var property in allPropertiesExceptComputed)
        {
            colMappings.Add(new MySqlBulkCopyColumnMapping(i, property.Name));
            i++;
        }

        bulkCopy.BulkCopyTimeout = bulkCopyTimeout;
        //bulkCopy.BatchSize = batchSize;
        bulkCopy.DestinationTableName = tempToBeInserted;
        var dataReader = ToDataTable(data, allPropertiesExceptComputed).CreateDataReader();
        bulkCopy.WriteToServer(dataReader);

        string mergeCondition = string.Join(" AND ", mergingProperties.Select(c => $"{columns[c.Name]}={columns[c.Name]} "));

        string executeStatement = $@"
                    REPLACE INTO {tableName} ({GetColumnsStringSqlServer(allPropertiesExceptKeyAndComputed, columns)})
                    SELECT {GetColumnsStringSqlServer(allPropertiesExceptKeyAndComputed, columns)} FROM {tempToBeInserted}
                    WHERE ({mergeCondition});

                    DROP TABLE {tempToBeInserted};";

        con.Execute(executeStatement, null, transaction as MySqlTransaction, commandTimeout);
    }
    catch (MySqlException ex)
    {
        if (ex.Message.Contains("Received an invalid column length from the bcp client for colid"))
        {
            string pattern = @"\d+";
            Match match = Regex.Match(ex.Message.ToString(), pattern);
            var index = Convert.ToInt32(match.Value) - 1;

            FieldInfo fi = typeof(MySqlBulkCopy).GetField("_sortedColumnMappings", BindingFlags.NonPublic | BindingFlags.Instance);
            var sortedColumns = fi.GetValue(bulkCopy);
            var items = (Object[])sortedColumns.GetType().GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(sortedColumns);

            FieldInfo itemdata = items[index].GetType().GetField("_metadata", BindingFlags.NonPublic | BindingFlags.Instance);
            var metadata = itemdata.GetValue(items[index]);

            var column = metadata.GetType().GetField("column", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(metadata);
            var length = metadata.GetType().GetField("length", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(metadata);
            throw new Exception(String.Format("Column: {0} contains data with a length greater than: {1}", column, length));
        }

        throw ex;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

Expected behavior A clear and concise description of what you expected to happen.

Additional context image

bgrainger commented 4 days ago

Extremely likely to be an issue local to your machine, such as a corrupted DLL file or interference from an anti-virus program.

Try updating the .NET 6 runtime to the latest version and checking signatures on all your DLLs.

shajiltetherfi commented 2 days ago

I have tried to update the latest .net 6 (6.0.35) and still get the same error . just we have Windows Defender as anti virus...

can you please re-open and help to check this problem

image

bgrainger commented 1 day ago

Possible duplicate of https://github.com/DapperLib/Dapper/issues/2124.

bgrainger commented 1 day ago

Are you using AOT compilation or .NET obfuscation or Fody or any other tool that rewrites the IL of your compiled assemblies?

shajiltetherfi commented 1 day ago

I have not used any tool to rewrite the IL. I downgraded from version 2.3.6 to 2.1.9, and it is now functioning correctly on the same server. Please let me know if there is any additional information I can provide to help identify the root cause of the issue on 2.3.6 . i badly wanted to update because the fixes and vulnerability which was made between 2.1.9 to 2.3.6 .

Also Please note this is happening in specific EC2 instance which we used to create via AMI.

bgrainger commented 1 day ago

Like Marc said at https://github.com/DapperLib/Dapper/issues/2124#issuecomment-2421767331, you need to provide a minimal repro in order for people to help you.

MySqlConnector doesn't emit any IL, so that makes me think it's perhaps more likely to be a bug in Dapper (although that also seems extremely unlikely to me).

Please note this is happening in specific EC2 instance which we used to create via AMI.

Do you mean this crash only happens on one particular EC2 instance (and not in local development, and not on any other EC2 instance you've deployed the code to)? If so, that instance is broken. Destroy it and recreate a new one with a clean image, then redeploy the code.

shajiltetherfi commented 7 hours ago

@bgrainger Yes, I agree with your point. I am trying to destroy and recreate a new AMI and remove old .net runtimes. keep you posted. I hope it will be resolve. Thanks Again @bgrainger @mgravell