diff options
author | Niklas Therning <niklas@therning.org> | 2016-11-15 18:22:33 +0300 |
---|---|---|
committer | Niklas Therning <niklas@therning.org> | 2016-11-16 11:14:25 +0300 |
commit | ed892ccf27849c082ce6ca46fa8b96d86ca7c329 (patch) | |
tree | 8240e5df0bcd09dfd2b8a84c769e5b22ef758a46 /mcs/class/Mono.Posix | |
parent | f3002a1f72df7165dd42b7abb6d5b1b5ccaa035b (diff) |
Prevent Mono.Posix from using multiple C runtimes on Windows
Since libMonoPosixHelper.dll is linked against ucrtbase.dll the C runtime
wrapper functions in it will call into ucrtbase.dll. Some pinvokes in
Mono.Unix.Native.Stdlib, however, bind directly to C runtime functions in
msvcrt. This is problematic if a resource (heap memory, file pointer, etc) is
allocated using one C runtime and then operated upon using funcitons form the
other C runtime. E.g., Stdlib.malloc() calls into a wrapper in
libMonoPosixHelper so it will use the ucrtbase heap while Stdlib.free() calls
directly into msvcrt's free() which will abort the process since it's called
with a pointer in an unknown heap.
This commit adds libMonoPosixHelper wrappers for all memory and file related
functions in Stdlib to ensure that all such functions use the same C runtime.
Some of the Mono.Posix tests still fail but at least the test suite doesn't
crash after this change. The test failures will be addressed in a future PR.
Diffstat (limited to 'mcs/class/Mono.Posix')
-rw-r--r-- | mcs/class/Mono.Posix/Mono.Unix.Native/Stdlib.cs | 56 | ||||
-rw-r--r-- | mcs/class/Mono.Posix/Mono.Unix/StdioFileStream.cs | 12 |
2 files changed, 46 insertions, 22 deletions
diff --git a/mcs/class/Mono.Posix/Mono.Unix.Native/Stdlib.cs b/mcs/class/Mono.Posix/Mono.Unix.Native/Stdlib.cs index e4c34cba317..86cdb7126fe 100644 --- a/mcs/class/Mono.Posix/Mono.Unix.Native/Stdlib.cs +++ b/mcs/class/Mono.Posix/Mono.Unix.Native/Stdlib.cs @@ -675,7 +675,8 @@ namespace Mono.Unix.Native { [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))] string newpath); - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_tmpfile")] public static extern IntPtr tmpfile (); private static object tmpnam_lock = new object (); @@ -704,18 +705,22 @@ namespace Mono.Unix.Native { } } - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fclose")] public static extern int fclose (IntPtr stream); - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fflush")] public static extern int fflush (IntPtr stream); - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fopen")] public static extern IntPtr fopen ( [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))] string path, string mode); - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_freopen")] public static extern IntPtr freopen ( [MarshalAs (UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(FileNameMarshaler))] string path, string mode, IntPtr stream); @@ -741,8 +746,8 @@ namespace Mono.Unix.Native { return setvbuf (stream, (IntPtr) buf, mode, size); } - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, - EntryPoint="fprintf")] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + EntryPoint="Mono_Posix_Stdlib_fprintf")] private static extern int sys_fprintf (IntPtr stream, string format, string message); public static int fprintf (IntPtr stream, string message) @@ -846,11 +851,12 @@ namespace Mono.Unix.Native { * vsscanf(3) */ - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fgetc")] public static extern int fgetc (IntPtr stream); - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, - SetLastError=true, EntryPoint="fgets")] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fgets")] private static extern IntPtr sys_fgets (StringBuilder sb, int size, IntPtr stream); public static StringBuilder fgets (StringBuilder sb, int size, IntPtr stream) @@ -866,22 +872,28 @@ namespace Mono.Unix.Native { return fgets (sb, sb.Capacity, stream); } - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fputc")] public static extern int fputc (int c, IntPtr stream); - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_fputs")] public static extern int fputs (string s, IntPtr stream); - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] - public static extern int getc (IntPtr stream); + public static int getc (IntPtr stream) + { + return fgetc (stream); + } [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] public static extern int getchar (); /* SKIP: gets(3) */ - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] - public static extern int putc (int c, IntPtr stream); + public static int putc (int c, IntPtr stream) + { + return fputc (c, stream); + } [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] public static extern int putchar (int c); @@ -889,7 +901,8 @@ namespace Mono.Unix.Native { [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] public static extern int puts (string s); - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_ungetc")] public static extern int ungetc (int c, IntPtr stream); [CLSCompliant (false)] @@ -993,10 +1006,12 @@ namespace Mono.Unix.Native { SetLastError=true, EntryPoint="Mono_Posix_Stdlib_clearerr")] public static extern int clearerr (IntPtr stream); - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_feof")] public static extern int feof (IntPtr stream); - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + SetLastError=true, EntryPoint="Mono_Posix_Stdlib_ferror")] public static extern int ferror (IntPtr stream); [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, @@ -1050,7 +1065,8 @@ namespace Mono.Unix.Native { SetLastError=true, EntryPoint="Mono_Posix_Stdlib_calloc")] public static extern IntPtr calloc (ulong nmemb, ulong size); - [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl)] + [DllImport (MPH, CallingConvention=CallingConvention.Cdecl, + EntryPoint="Mono_Posix_Stdlib_free")] public static extern void free (IntPtr ptr); // malloc(3): diff --git a/mcs/class/Mono.Posix/Mono.Unix/StdioFileStream.cs b/mcs/class/Mono.Posix/Mono.Unix/StdioFileStream.cs index 7eed08157b0..1d0ef97e9f7 100644 --- a/mcs/class/Mono.Posix/Mono.Unix/StdioFileStream.cs +++ b/mcs/class/Mono.Posix/Mono.Unix/StdioFileStream.cs @@ -60,35 +60,43 @@ namespace Mono.Unix { public StdioFileStream (string path) { + if (path == null) + throw new ArgumentNullException ("path"); InitStream (Fopen (path, "rb"), true); } public StdioFileStream (string path, string mode) { + if (path == null) + throw new ArgumentNullException ("path"); InitStream (Fopen (path, mode), true); } public StdioFileStream (string path, FileMode mode) { + if (path == null) + throw new ArgumentNullException ("path"); InitStream (Fopen (path, ToFopenMode (path, mode)), true); } public StdioFileStream (string path, FileAccess access) { + if (path == null) + throw new ArgumentNullException ("path"); InitStream (Fopen (path, ToFopenMode (path, access)), true); InitCanReadWrite (access); } public StdioFileStream (string path, FileMode mode, FileAccess access) { + if (path == null) + throw new ArgumentNullException ("path"); InitStream (Fopen (path, ToFopenMode (path, mode, access)), true); InitCanReadWrite (access); } private static IntPtr Fopen (string path, string mode) { - if (path == null) - throw new ArgumentNullException ("path"); if (path.Length == 0) throw new ArgumentException ("path"); if (mode == null) |