Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix EntryPointNotFoundException in InOutOfProcHelper constructor #1120

Merged

Conversation

0xced
Copy link
Contributor

@0xced 0xced commented Jun 16, 2021

The constructor of InOutOfProcHelper would throw a System.EntryPointNotFoundException when running on a non-Windows platform such as Mono on Linux or macOS:

GetModuleHandle assembly:<unknown assembly> type:<unknown type> member:(null)
  at (wrapper managed-to-native) Microsoft.Data.Common.SafeNativeMethods.GetModuleHandle(string)
  at Microsoft.Data.SqlClient.InOutOfProcHelper..ctor () [0x00006] in <de6019a43b5544ecb987a2a77d294ad3>:0
  at Microsoft.Data.SqlClient.InOutOfProcHelper..cctor () [0x00000] in <de6019a43b5544ecb987a2a77d294ad3>:0

We avoid the EntryPointNotFoundException by returning early on non-Windows platforms where the module can't be inside the SQL Server process anyway.

The constructor of InOutOfProcHelper would throw a `System.EntryPointNotFoundException` when running on a non-Windows platform such as Mono on Linux or macOS:

```
GetModuleHandle assembly:<unknown assembly> type:<unknown type> member:(null)
  at (wrapper managed-to-native) Microsoft.Data.Common.SafeNativeMethods.GetModuleHandle(string)
  at Microsoft.Data.SqlClient.InOutOfProcHelper..ctor () [0x00006] in <de6019a43b5544ecb987a2a77d294ad3>:0
  at Microsoft.Data.SqlClient.InOutOfProcHelper..cctor () [0x00000] in <de6019a43b5544ecb987a2a77d294ad3>:0
```

We avoid the EntryPointNotFoundException by returning early on non-Windows platforms where the module can't be inside the SQL Server process anyway.
@cheenamalhotra
Copy link
Member

Is there a way to reproduce the issue you mentioned on Windows?

@0xced
Copy link
Contributor Author

0xced commented Jun 18, 2021

Well, you can't reproduce this issue on Windows since kernel32.dll exists on Windows so you won't get an EntryPointNotFoundException. But here is how to reproduce it on Linux and macOS (using the published Microsoft.Data.SqlClient 3.0.0 NuGet package). Note that it requires mono to be installed and docker to be running.

mono --version >/dev/null && echo "✅ mono is installed" || echo "❌ mono must be installed"
docker info >/dev/null && echo "✅ docker is running" || echo "❌ docker must be running"
git clone https://github.com/0xced/DockerRunner
cd DockerRunner
git checkout 080e64d8f8dd5dd63119b20eda22fd4f2a56c8a8
dotnet test --framework net472 --filter DisplayName~SqlServer2019Test tests/SqlServer/DockerRunner.Tests.SqlServer.csproj

And here's the failure that you should get:

[xUnit.net 00:00:04.61]     DockerRunner.Tests.SqlServer.SqlServer2019Test.StartDockerDatabaseContainer [FAIL]
  Failed DockerRunner.Tests.SqlServer.SqlServer2019Test.StartDockerDatabaseContainer [3 s]
  Error Message:
   System.TypeInitializationException : The type initializer for 'Microsoft.Data.SqlClient.InOutOfProcHelper' threw an exception.
---- System.EntryPointNotFoundException : GetModuleHandle assembly:<unknown assembly> type:<unknown type> member:(null)
  Stack Trace:
    at Microsoft.Data.SqlClient.SqlConnectionString..ctor (System.String connectionString) [0x0000d] in <de6019a43b5544ecb987a2a77d294ad3>:0 
  at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnectionOptions (System.String connectionString, Microsoft.Data.Common.DbConnectionOptions previous) [0x00000] in <de6019a43b5544ecb987a2a77d294ad3>:0 
  at Microsoft.Data.ProviderBase.DbConnectionFactory.GetConnectionPoolGroup (Microsoft.Data.Common.DbConnectionPoolKey key, Microsoft.Data.ProviderBase.DbConnectionPoolGroupOptions poolOptions, Microsoft.Data.Common.DbConnectionOptions& userConnectionOptions) [0x0003e] in <de6019a43b5544ecb987a2a77d294ad3>:0 
  at Microsoft.Data.SqlClient.SqlConnection.ConnectionString_Set (Microsoft.Data.Common.DbConnectionPoolKey key) [0x00008] in <de6019a43b5544ecb987a2a77d294ad3>:0 
  at Microsoft.Data.SqlClient.SqlConnection.set_ConnectionString (System.String value) [0x000c8] in <de6019a43b5544ecb987a2a77d294ad3>:0 
  at DockerRunner.DockerDatabaseContainerRunner.StartAsync (DockerRunner.DockerDatabaseContainerConfiguration configuration, System.EventHandler`1[TEventArgs] runningCommand, System.EventHandler`1[TEventArgs] ranCommand, System.EventHandler`1[TEventArgs] sqlCommandExecuting, System.Boolean waitOnDispose, System.Threading.CancellationToken cancellationToken) [0x001c1] in <fd1e156180b74e3fac1824c62b5de493>:0 
  at DockerRunner.DockerDatabaseContainerRunner.StartAsync (DockerRunner.DockerDatabaseContainerConfiguration configuration, System.EventHandler`1[TEventArgs] runningCommand, System.EventHandler`1[TEventArgs] ranCommand, System.EventHandler`1[TEventArgs] sqlCommandExecuting, System.Boolean waitOnDispose, System.Threading.CancellationToken cancellationToken) [0x004fd] in <fd1e156180b74e3fac1824c62b5de493>:0 
  at DockerRunner.Tests.DockerDatabaseContainerRunnerTest`1[TConfiguration].StartDockerDatabaseContainer () [0x000fa] in <03c47b46daea4c03b1367e34b1a6c4c0>:0

@0xced
Copy link
Contributor Author

0xced commented Jun 18, 2021

I'm still a little worried about running RuntimeInformation.IsOSPlatform(OSPlatform.Windows) on .NET Framework 4.6.1. As @JRahnama mentioned, IsOSPlatform is documented to be available since .NET Framework 4.7.1, not 4.6.1. Are we sure that this code path is exercised on a machine running .NET Framework 4.6.1 on Azure Pipelines? It would be terrible to fix a bug on Mono and add a regression that throws NotSupportedException or NotImplementedException on .NET Framework 4.6.1.

@cheenamalhotra
Copy link
Member

cheenamalhotra commented Jun 18, 2021

I don't think it's an issue honestly. If it were, compilation would fail. I think the docs may be wrong.
We build with net461 as target framework, and the DLL contains this definition.
We are getting it resolved from .NET Build Extensions available when we build.

image

I will check if we need to include it in nuspec for ensuring it's availability, it shouldn't hurt.

@cheenamalhotra cheenamalhotra added this to the 4.0.0-preview1 milestone Jul 5, 2021
@cheenamalhotra cheenamalhotra merged commit 00cbff1 into dotnet:main Jul 5, 2021
@0xced 0xced deleted the Fix-FixEntryPointNotFoundException branch July 5, 2021 22:06
Kaur-Parminder added a commit to Kaur-Parminder/SqlClient that referenced this pull request Aug 23, 2021
Kaur-Parminder added a commit to Kaur-Parminder/SqlClient that referenced this pull request Aug 26, 2021
JRahnama pushed a commit that referenced this pull request Sep 14, 2021
@0xced
Copy link
Contributor Author

0xced commented Sep 23, 2021

I deleted my comment and reposted it in an open issue rather than in a merged pull request: #1263 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants