Fail cleanly when MonoPosixHelper.dll version is wrong (bug #35655)
[mono.git] / mcs / class / Mono.Posix / Mono.Unix.Native / Stdlib.cs
index c2e50b8d259eecf638d0c6738d2fe4ca677119f4..e4c34cba317f28629d885cb370e536fc3cabb29f 100644 (file)
@@ -381,6 +381,42 @@ namespace Mono.Unix.Native {
                internal const string LIBC = "msvcrt";
                internal const string MPH  = "MonoPosixHelper";
 
+               // It is possible for Mono.Posix and MonoPosixHelper to get out of sync,
+               // for example if NuGet does something weird. To mitigate this, anyone
+               // editing Mono.Posix needs to observe two rules:
+               //   1. When introducing C-interface changes to MonoPosixHelper, update
+               //      the version strings in VersionCheck below and also
+               //      Mono_Unix_VersionString in the C sources.
+               //   2. Any class which performs a DllImport on Stdlib.MPH needs to call
+               //      Stdlib.VersionCheck in its static constructor.
+
+               [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl,
+                               EntryPoint="Mono_Unix_VersionString")]
+               private static extern IntPtr VersionStringPtr ();
+               private static bool versionCheckPerformed = false;
+               internal static void VersionCheck ()
+               {
+                       if (versionCheckPerformed)
+                               return;
+
+                       // This string is arbitrary; it matters only that it is unique.
+                       string assemblyVersion = "MonoProject-2015-12-1";
+                       string nativeVersion = Marshal.PtrToStringAnsi (VersionStringPtr ());
+                       if (assemblyVersion != nativeVersion)
+                       {
+                               throw new Exception ("Mono.Posix assembly loaded with a different version (\""
+                                       + assemblyVersion + "\") than MonoPosixHelper (\"" + nativeVersion
+                                   + "\"). You may need to reinstall Mono.Posix.");
+                       }
+
+                       versionCheckPerformed = true;
+               }
+
+               static Stdlib ()
+               {
+                       VersionCheck ();
+               }
+
                internal Stdlib () {}
 
                #region <errno.h> Declarations