Mono 5.0.0 Release Notes

Release date: 10 May 2017

Release History

  • 5.0.0.100 - Stable release (10 May 2017)
  • 5.0.0.94 - Beta 2 (03 May 2017)
  • 5.0.0.78 - Beta 1 (26 Apr 2017)
  • 5.0.0.61 - Alpha 3 (19 Apr 2017)
  • 5.0.0.48 - Alpha 2 (11 Apr 2017)
  • 5.0.0.42 - Alpha 1 (06 Apr 2017)

Highlights

In Depth

Breaking changes

Mono 5.0 implements the .NET 4.6 behavior regarding CultureInfo.CurrentCulture and CultureInfo.CurrentUICulture. On previous versions they used to be stored on thread-locals but now are stored on the execution context, meaning their values follow async Tasks. For more information see MSDN page

C# compiler

csc

The Roslyn C# compiler is now available on Mono and it’s called csc. It’s the same compiler available on Windows / Visual Studio with full support for C# 7. Both msbuild and xbuild have been updated to call the csc compiler under the hood instead of mcs.

Replacing mcs with csc in user scripts should be straightforward but small issues can arise as command line arguments accepted by csc and features are not identical to mcs. For example, csc generates Portable PDB (.pdb) debug files instead of Mono’s MDB (.mdb) format. It also can’t do full signing on non-Windows platforms, use the /publicsign switch instead or use delay signing and sign the assembly with the sn tool after the build.

Note: mcs defined the __MonoCS__ symbol and some users incorrectly used it to conditionally compile code specific to Mono. This is considered bad practice and won’t work anymore now that csc is the default compiler. You can detect whether you’re running on Mono at runtime instead.

C# 7 adds a number of new features to the C# language

  • out variables:
    • You can declare out values inline as arguments to the method where they are used.
  • Tuples
    • You can create lightweight, unnamed types that contain multiple public fields. Compilers and IDE tools understand the semantics of these types.
  • Pattern Matching
    • You can create branching logic based on arbitrary types and values of the members of those types.
  • ref locals and returns
    • Method arguments and local variables can be references to other storage.
  • Local Functions
    • You can nest functions inside other functions to limit their scope and visibility.
  • More expression-bodied members
    • The list of members that can be authored using expressions has grown.
  • throw Expressions
    • You can throw exceptions in code constructs that previously were not allowed because throw was a statement.
  • Generalized async return types
    • Methods declared with the async modifier can return other types in addition to Task and Task<T>.
  • Numeric literal syntax improvements
    • New tokens improve readability for numeric constants.

The new features in C# 7 can also be explored interactively as a Xamarin Workbook.

mcs

The Mono C# compiler is still available but it has not been updated to include C#7 features. The compiler is still maintained and all reported bugs have been fixed.

MSBuild

Over the past year we have been working to integrate the open-sourced msbuild build tool into Mono. It is now available as part of your Mono installation, and it is the same MSBuild that is used on .NET on Windows.

This resolves numerous incompatibilities we had in our previous xbuild implementation.

xbuild

Mono’s historical implementation of MSBuild called xbuild is now deprecated. We encourage everyone to switch to the msbuild command which is now available on Mono as well.

Reference assemblies

The reference assemblies were updated to fully match the .NET 4.6.2 API set. This means that you no longer get compilation errors about missing classes/methods when building against one of the .NET profiles via msbuild/xbuild.

Note that at runtime certain APIs that Mono doesn’t (yet) implement will still throw an exception.

Tools

pdb2mdb

The pdb2mdb tool was updated so it no longer crashes when run against an assembly that has a Portable PDB debug symbols available.

csharp

The csharp REPL and scripting tool, which is based on the mcs compiler, now supports script-and-REPL-specific command line arguments, which are delimited by either the -s or -- arguments. These arguments are further made available in the Args global for easy processing in scripts.

It is now possible to write self-executing scripts with simple and unambiguous access to command line arguments:

#!/usr/bin/env csharp -s

Args.Length

nunit

Deprecation of Mono-bundled version of NUnit:

Mono used to ship with a forked copy of NUnit 2.4 that we used for testing Mono itself. For historical reasons it was never updated and is ancient at this point (it was released nearly 10 years ago!).

We moved to NUnitLite for testing Mono so we decided to deprecate the version we ship.

The nunit-console command will print a warning now. Compiling new projects against the NUnit DLLs from GAC will fail with an error message (existing test assemblies continue to work).

We recommend that you use a recent version of NUnit from NuGet or the project’s website instead.

CoreFX + Reference Source Adoption

As we announced we are adopting a new strategy to share code with .NET. With this release we started this effort where the code is shared between .NET Core and Mono and not just the Reference Source release.

Windows

The build system was fixed so it works without setting the git config --global core.autocrlf input setting which makes building Mono on Windows easier.

macOS

AppleTLS stack

The Mono.framework package that we distribute for macOS now uses the AppleTLS stack for implementing our SSL/TLS transport. This brings full support for TLS 1.2 for SslStream and our various HTTP web clients.

In the initial preview release, AppleTLS has two known issues:

  • Under certain circumstances, programs using AppleTLS may halt and present a GUI dialog requesting keychain access. More information and bugzilla entry here.
  • SecCertificateCreateWithData, and thus many X.509 functions, currently behave differently when given an invalid certificate on each of 10.9, 10.11, and 10.12. Bugzilla entry here.

We do offer a way of using the old SSL/TLS stack. Set the MONO_TLS_PROVIDER environment variable to legacy to use the old Mono managed TLS 1.0 stack. From your shell, you can do it like this:

export MONO_TLS_PROVIDER=legacy

libjpeg Update in macOS Package

The macOS SDK package now contains an updated libjpeg library that resolves the issue described in CVE-2013-6629. Our Mono distribution for macOS now includes an updated libjpeg.

Runtime

SIMD Acceleration support

Generating SIMD accelerated native code for the classes in the Mono.Simd assembly is deprecated in this release, and it will be removed in +2 releases. Users should transition to using the Vector classes, which are part of the official .NET class libraries.

Environment Memory Management And System.Configuration

As per the Unix specification, getenv may return a pointer into static memory. Future calls to getenv can overwrite the memory returned from previous calls to getenv. Mono kept many pointers into this memory while concurrently calling getenv on multiple threads. We now lock around the environment-changing functions and to duplicate all returned strings.

Unfortunately, Mono will use the environment to find which configuration file to read for System.Configuration. Configurations that were set might not have been used, as managed code was seeing nulls. This is how the bug surfaced, it is not hypothetical. Users who set a custom configuration file (via MONO_CFG_DIR) are encouraged to check that using previously-ignored configuration files does not lead to unexpected breakage.

Match semantics of rethrow instruction with .NET runtime

Mono used to cut off the stack trace at the point where an exception is re-thrown, however, it should retain the stack trace if rethrow is used.

Experimental runtime interpreter

We revived the interpreter back from the old days (aka. mint). It now supports generics, and was updated to match internal API changes. It is disabled by default and shouldn’t be used in production yet.

The interpreter will be an execution option to the current runtime.

Clean-ups around native crashes

Native crashes now end up a single handler mono_handle_native_crash, that tries to provide as much information as possible. Also, SIGILL won’t get wrapped into a managed exception anymore but results into a native crash.

Internal Documentation

We have enabled Doxygen for documentation of runtime internals. Going forward, this should help us onboard new contributors and make the codebase easier to navigate and understand.

Lazy array interfaces

One curious aspect of C# is that arrays implement invariant interfaces as if they were covariant. This happens for IList<T>, ICollection<T> and IEnumerable<T> which means, for example, that string[] implements both IList<string> and IList<object>.

Mono traditionally implemented this by creating the runtime-side metadata for all of those interfaces and that came with an extraordinary memory cost of creating a lot of interfaces that never ended up being referenced by C# code.

With Mono 5.0 we now treat those interfaces as magic/special and use a different casting code-path. This allows them to be lazily implemented in arrays, which can save a lot of memory in LINQ-heavy workloads. As part of this work we refactored the casting code in the JIT to be simpler and more maintainable.

Memory usage

Improvements in the runtime representation of the type system should yield a 5% memory saving in most workloads. It was achieved by using a more efficient representation for arrays and generic instances.

A linearizable property bag was added to replace the current mechanism of rare fields in runtime metadata. More rarely used fields were moved to use it as they now use significantly less memory when used.

SGen Improvements

As of this release we are enabling concurrent SGen as the default mode on desktop platforms. This mode significantly reduces the time spent in major collections, by doing most of the work concurrently with the application. In order to use the old serial collector you can pass to the environment MONO_GC_PARAMS=major=marksweep.

A new parallel SGen mode has been added for majors. This mode uses multiple workers in order to finish a concurrent collection and it is currently experimental. If you are still experiencing large pauses with the concurrent collector, you can try out the parallel mode by passing MONO_GC_PARAMS=major=marksweep-conc-par.

SGen uses an optimized custom implementation of quicksort to improve the performance of some GC operations. Previously, it selected a poor choice of pivot, which could lead to worst-case time complexity in some circumstances. It has been rewritten with an improved pivot strategy.

This release includes some performance improvements in ephemeron processing, which also translate to shorter collections. Ephemerons are an internal structure used by the SGen to implement the semantics of ConditionalWeakTable. This also includes a fix for a long-standing leak when using and disposing of a lot of these structures.

Major block allocation and freeing was tweaked in order to reduce fragmentation of the virtual memory space.

SIMD Register Scanning

Certain compiler optimizations can lead to object references being stored in SIMD registers, for example, during an optimized copy of an array of references. Previously, the runtime did not scan these registers, which could cause objects to be prematurely freed if the garbage collector happened to run while the only reference to an object resided in such a register. The runtime now correctly scans these registers for object references during garbage collection.

Static Analysis

We are investing in static analysis of the runtime to verify our use of locks, signals, and global state. This should help reduce concurrency errors, improving correctness and stability. As a first step, we have already caught some locking errors in the garbage collector.

Symbolification

The runtime crash stack traces now include information on managed stack traces to allow them to be symbolificated. Tooling was adjusted to handle the slightly different format.

Thread.Abort hardening

The runtime was hardened to further its resilience in face of thread aborts. It now won’t abort in-flight class constructors. Thread abort is important for application using multiple AppDomains.

ThreadAbortException

ThreadAbortException remains set during stack unwinding unless manually unset. While inside of a function call inside of a catch block for the exception, it was possible for us to see the set ThreadAbortException and behave as if the call inside of the catch block threw it. This has been fixed.

Unwinding on Android

On a native crash on Android, the Mono runtime tried to dlopen libcorkscrew or libunwind (depending on what is available) in order to obtain a native stack trace. However, this approach was unreliable, as some devices don’t even ship said libraries. Furthermore, Android will restrict the dlopen syscall in an unfavorable way for this approach in a future version.

We changed our approach by trying to do less work: We now rely on a system process by Android aka. debuggerd to provide us a native stack trace. On some Android versions this requires us to set DUMPABLE.

Workaround for .NET Standard NuGets on desktop

Some .NET Standard NuGets like System.IO.Compression resolve to assemblies that won’t work with Mono on Desktop. To handle this we implemented a series of workarounds:

  • Deny loading problematic assemblies. They will be handled as if they did not exist
  • Deny remapping to problematic assembly versions. The system version will be used instead.

Windows Support

Mono can now run on Win64.

Bring PowerPC back to life

Mono can bootstrap on ppc64le.

Bug Fixes

  • 7467 DefaultNonPersistentConnectionLimit is to low
  • 12571: Usage of XElement with XmlAnyElementAttribute is not supported by XmlSerializer
  • 16628 ilasm crashes on input file
  • 19594: WebException.Response is null when https request needs proxy authentication
  • 34715: HttpClient incorrectly works with multiple headers
  • 34802: Debugger crash on break-all, step into sequence.
  • 35536: Dns.GetHostEntry no longer supports IPv6
  • 35662 Type System.ServiceModel.Security.Tokens.BinarySecretSecurityToken is missing in assembly System.IdentityModel
  • 39444: Action ReflectedType differs from Delegate ReflectedType for virutal methods
  • 39832: SIGSEGV when running roslyn
  • 40603: Mono can’t parse Date in DB wich is in format: "2016-02-04 10:39:11Z"
  • 41133 System.MethodAccessException: Method ‘System.Net.WebHeaderCollection:AddValue (string,string)’ is inaccessible from method ‘System.Net.Http.HttpClientHandler’
  • 41914 Race condition in named mutex
  • 41953: Wrong directory name used for libraries on Red Hat & SUSE (lib64 -> lib)
  • 41995: [Concurrent SGen] Assertion: should not be reached at sgen-marksweep.c:1103
  • 42226 WCF client Expecting FaultException<TDetail> raising NotImplemented Exception instead When <FaultActor> element is provided.
  • 42271: COOP: gc unsafe mode when printing native backtrace causes crash if GC is triggered
  • 42584 InternalError / Crash when using System.Net.Http and PCL library
  • 42715 Directory.GetFiles & AllDirectories might fail
  • 42843: XmlSerializer does not deserialize UTC Time values on Xamarin.Android but works well on windows.
  • 43921 System.Threading.ThreadHelper.ThreadStart_Context tries to allocate, crashes
  • 44025 FTP download issue with IPv6
  • 44109 NetworkCredential does not convert SecureString
  • 44164: gosharp-regexp benchmark triggers unwinding crash when profiling
  • 44168: Can use non-accessible member with nameof
  • 44296 Multicast not working on Android 7.0 devices
  • 44341: No way of updating async method local variables
  • 44381: Debugger crash with domain unloading and VSTU
  • 44402: Array doesn’t implement non-generic IEnumerable
  • 44406: Xamarin.Mac.Socket exception:An address incompatible with the requested protocol was used
  • 44413: HttpHeaders.TryAddWithoutValidation behaves differently from .NET
  • 44440: Attempting to JIT error in function with pointer arithmetic
  • 44549 Ide Shuts down: System.ArgumentException: Item has already been added. Key in dictionary: ‘XamlG’ Key being added: ‘XamlG’
  • 44552 Domain end unload event arrives before start unload event
  • 44624: Connecting to SQL Server using IPv4 exception.
  • 44707: RemotingConfiguration.Configure() Throws RemotingException Because it Cannot Load ‘machine.config’
  • 44714 xbuild fails to find VB.NET compiler
  • 44729 Type.GetType("blah",true,false) throws TypeLoadException without message
  • 44751: Incorrect code flow analysis with goto and out parameter causes CS0177
  • 44843: SqlCommand.ExecuteReaderAsync throws NotImplementedException
  • 44937 System.Diagnostics.StartProcess does not detect dotnetcore compiled assemblies as managed
  • 44978: HttpClientHandler.SendAsync should throw HttpRequestException for proxy auth failure
  • 44982: SourceFileFilter does not filter on specific file when static ctor exists
  • 44994 DeflateStream decompression is incomplete if reading byte-by-byte
  • 45108: Proxy credentials not used for https url
  • 45129: Uri.IsWellFormedUriString returns incorrect result for relative uris beginning with slash
  • 45131: Array of double*[] being treated as non-blittable when marshaled
  • 45137 Seeing new AAPT0000 errors when building certain projects against master
  • 45270: Cannot add System.Reactive to watchOS Extension project
  • 45286: C# string interpolation line does not compile on OSX but does on MSBuild
  • 45371: SIGSEGV occurs when making call from native to managed code
  • 45683: Add fallback implementation to compile with glibc that lacks CPU_COUNT
  • 45761 After network reconnected, web request fails for a couple of minutes with a NameResolutionFailure
  • 45774: Wrong scopes in .mdb in case of foreach loop
  • 45788: Marshaling a native NULL pointer to a managed array creates a new zero sized array
  • 45841: x86 codegen produces wrong result for float operation
  • 45994 TLS connections on non-standard ports result in incorrect Server Name Indication value
  • 46175: If the RSA will be used by multiple threads, it has a variety of exceptions.
  • 46190: Overload resolution fails in a case where methods use a named parameter in different positions
  • 46250 Type.GetType with throwOnError true doesn’t throw for a generic instance type with too few generic arguments
  • 46288: function mono_string_to_byvalwstr may cause access violation
  • 46456: CultureInfo("ug-CN") not found in Xamarin.Android and Xamarin.iOS
  • 46536 [coop] mono_os_mutex_destroy: pthread_mutex_destroy failed with "Device or resource busy" (16)
  • 46538: System.Net.WebClient.OpenReadAsync/OpenReadTaskAsync do not work for file:// URLs
  • 46602 MobileAuthenticatedStream.AuthenticateAsServer() via EndPointListener
  • 46712 btls fails to build with gcc is v4.4.7 or earlier as they lack alignof/alignas
  • 46739: Assembly::Evidence property crashes for unbaked assembly
  • 46806: opspecial011.Program.DynamicCSharpRunTest test in ms-test-suite fails with "Operator ‘+’ cannot be applied to operands"
  • 46929: Datetime error on Mono.data.Sqlite
  • 47152: AOT attempts at Xamarin.Mac.dll crash mono
  • 47156 * Assertion at class.c:2093
  • 47205: Uri.TryCreate throws exception
  • 47221 Thread.Name can only be set once inside async callback
  • 47353: Mono.CSharp.MetadataImporter.set_IgnoreCompilerGeneratedField not found when running Cake on Mono 4.8
  • 47388: Memory leak when using FromSynchronizationContext
  • 47549: Chunked encoding error when writing zero buffer
  • 47672: Invalid error CS0314
  • 47762: EXC_BAD_ACCESS when unloading assembly
  • 47867 assert at sre.c:1553 in System.Reflection.Emit.TypeBuilder.create_runtime_class
  • 48016 System.Net.NetworkInformation.DnsAddresses is always empty. Fix included.
  • 48429: Mono fails to marshal fixed buffer fields as unicode
  • 48875: Socket.AddSockets throw exception with weird param
  • 49056: Assertion at /Users/builder/data/lanes/3969/44931ae8/source/xamarin-macios/external/mono/mono/mini/mini-generic-sharing.c:2351, condition `info’ not met
  • 49686 System.NotImplementedException at System.Reflection.Emit.DynamicMethod.GetCustomAttributes (System.Type attributeType, Boolean inherit)
  • 50242: Cannot use MSXSL format-date/format-time XPath extension functions on non-Windows platforms
  • 50529: crash in thread-native-exit.exe
  • 50789: JITting large method fails (condition lvregs_len < 1024 not met)
  • 51166: mcs converts new T[0] into Array.Empty<T>() which is not conform C# spec
  • 51219 ves_icall_System_Threading_ThreadPool_RequestWorkerThread called after threadpool cleanup
  • 51330: Inline Enum::GetHashCode implementation
  • 51506: C# compiler fails for constrained generics with yield return
  • 51545 [Crash] mono_threads_platform_set_priority: unknown policy 3
  • 51562: NullReferenceException in BTLS X509CertificateImplBtls.Import()
  • 51653: mono_thread_info_wait_one_handle ignored alertable argument
  • 52157 SocketTest.ConnectedProperty test fails in FullAOT Linux runs
  • 52345 Process has exited, so the requested information is not available
  • 52429 Shutdown hang then crash in Finalizer thread
  • 52437: Random NullReferenceExceptions in StringBuilder.ThreadSafeCopy
  • 52448: StreamContent apparently needs to rewind stream before sending it
  • 52475: MTOUCH: error MT3001: Could not AOT the assembly
  • 52549 error: mono_w32socket_convert_error: no translation into winsock error for (41) "Protocol wrong type for socket"
  • 52600: Full AOT: Strange combination of structs, generics, and enums causes runtime failure
  • 52743: denied loading problems
  • 52845 [Cycle 9] Satellite assemblies not bundled when using "Bundle assemblies into native code" due to "unknown escape sequence" error from gcc during mkbundle step
  • 52866: F# sprintf AOT bug still exists
  • 52899: mprof-report missing filenames in coverage xml output when using portable pdbs
  • 53066: Can’t Build Project in Debug with "Could not AOT the assembly"
  • 53231: csc doesn’t unify same file passed multiple times when one path is relative
  • 53278: Two coreclr SIMD test failures (one regression from 4.8)
  • 53481 The threadpool crashes on XS CI
  • 53684: Crash when enumerating directory and selecting the first file
  • 53689 [Test] Certificate7 disabled due to SecCertificateCreateWithData does different things on 10.11 vs 10.12 with invalid certificates
  • 53843: Mono deadlocks on shutdown while waiting for a process which has died
  • 53890 Regression: Native crash while running tests with xunit with mono 2017-02 branch, works with 4.8.0.520
  • 54448: Unable to revert to thread-local storage for CurrentThread.CultureInfo
  • 55041: Stripping mscorlib in simple example changes IntPtr (5) behavior?
  • 55626 FSharp.NET.Sdk bundled with mono should not override FscToolPath and FscToolExe properties
  • 55681 System.Reflection.Emit.ModuleBuilder.build_metadata bug when running FAKE’s test suite

Contributors

Aaron Bockover, Abdur Rehman, Aleksey Kliger, Alexander Köplinger, Alexander Kyte, Alex Earl, Alexis Christoforides, Alex Rønne Petersen, Andrey Bolkonsky, Andi McClure, Ankit Jain, Atsushi Eno, Bernhard Urban, Chris Hamons, cmp, Dave Curylo, David Karlaš, Dmitriy Loktionov, Egor Bogatov, faulpeltz, Henric Müller, James Venning, Jason Imison, Jens Ehrhardt, João Matos, Johan Lorensson, Jonathan Chambers, Jon Purdy, Jo Shields, Josh Peterson, Katharina Bogad, Kenneth Skovhede, Legowo Budianto, Lluis Sanchez, Ludovic Henry, Marcos Henrich, Marek Habersack, Marek Safar, Marius Ungureanu, Mark Probst, Martin Baulig, Michael DeRoy, Miguel de Icaza, Mikayla Hutchinson, Mike Voorhees, Mikko Korkalo, Neale Ferguson, Niklas Therning, Pei Su, Rodrigo Kumpera, Roger Vuistiner, Rolf Bjarne Kvinge, Sebastian Scheibner, Sebastien Pouliot, Sergei Trofimovich, Shay Rojansky, Swaroop Sridhar, Sylvan Clebsch, Tautvydas Žilys, Vincent Povirk, Vlad Brezae, Vladimir Kargov, Vladimir Panteleev, Zoltan Varga