The saga of the Oracle client and the “Attempted to read or write protected memory” exception

On one of the project’s I worked on recently, we had a strange problem whereby the application was deployed to multiple servers and on all but one, ran perfectly. On this one server we were seeing, in the log file, that we were getting exceptions with the message “Attempted to read or write protected memory”.

Let’s face it if the code works on all other boxes, the likelihood was a configuration or installation issue on the one anomaly machine. So I knocked together a very simple Oracle client (sample code listed below) to prove that the issue was unrelated to the software I maintained (you know how it is, you might be pretty sure where the problem is but sometimes you have to also prove it to others).

try
{
   var connection = new OracleConnection(connectionString);
   connection.Open();

   var command = connection.CreateCommand();
   command.CommandType = CommandType.Text;
   command.CommandText = queryString;

   var reader = command.ExecuteReader();

   while (reader.Read())
   {
      Console.WriteLine(reader.GetString(0));
   }
}
catch (Exception e)
{
   Console.WriteLine(e.Message);
   Console.WriteLine(e.StackTrace);
}

Obviously you’ll need to supply your own connectionString and queryString if using this snippet of code.

Indeed this simple client code failed with the same issue and hence it was definitely nothing to do with my application (and yes the same sample code was also tested on the working servers and worked perfectly).

We also connected to Oracle via sqlplus and all seemed fine, using the same connection details and query that we were using in the failing application.

Upon further investigation it became clear that multiple (well two) Oracle client installs existed on the machine and therefore it seemed likely our app was somehow trying to connect via a newer version of the Oracle client.

Luckily the web came to the rescue, with this following configuration code which allows us to point our .NET client code to a specific version of an Oracle client installation.

<configSections>
   <section name="oracle.dataaccess.client"
    type="System.Data.Common.DbProviderConfigurationHandler, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
  
<oracle.dataaccess.client>
   <settings>
      <add name="DllPath" value="c:\oracle\product\10.2.0\client_2\BIN"/>
   </settings>
</oracle.dataaccess.client>