[Mono-list] Debug.Assert - a cross-platform issue

Jonathan Pryor jonpryor at vt.edu
Sat Nov 22 02:43:37 UTC 2014


On Nov 21, 2014, at 7:25 PM, MarLOne <InfoSeeker002 at gmail.com> wrote:
> It will be good if these classes and assemblies from Microsoft open-sources are incorporated verbatim into Mono to replace its inconsistent code.

This will not be possible, for (at least) three reasons:

1. That code is also shared by Xamarin.Android, Xamarin.iOS, and Xamarin.Mac, all of which lack System.Configuration.dll, and the .NET DefaultTraceListener relies upon System.Configuration (via DiagnosticsConfiguration).

2. There are several CAS demands, which don't make sense on Mono.

3. The default code to write messages is useless outside of Windows, as no other platform has OutputDebugString():

	https://github.com/Microsoft/referencesource/blob/9da503f9ef21e8d1f2905c78d4e3e5cbb3d6f85a/System/compmod/system/diagnostics/DefaultTraceListener.cs#L182-191

This doesn't mean that the .NET source can't be taken *and modified* for use off Windows, but it can't be used as-is.

> I have to thank Microsoft to open-source the .Net library allowing me to read ...  default values for the System.Diagnostics.DefaultTraceListener.
> The default value of property that determines the reaction of Debug.Assert is set here:  assertuienabled

The hilarious thing is that AssertUiEnabled does not alone control actual runtime behavior!

	https://github.com/Microsoft/referencesource/blob/9da503f9ef21e8d1f2905c78d4e3e5cbb3d6f85a/System/compmod/system/diagnostics/DefaultTraceListener.cs#L105-107

The behavior of DefaultTraceListener.Fail() depends on *both* DefaultTraceListener.AssertUiEnabled *and* DefaultTraceListener.UiPermission, which is a private property that demands the UIPermissionWindow.SafeSubWindows CAS permission:
	
                try {
                    new UIPermission(UIPermissionWindow.SafeSubWindows).Demand();
                    return true;
                }
                catch {
                    return false;
                }

This explains how they can sanely have a non-GUI Windows service use Debug.Assert() and have it not hang when there's no Window Station: just have the startup code set security permissions which denies UIPermissionWindow.SafeSubWindows...

This doesn't at all answer how things should work off Windows. You can reasonably argue that DefaultTraceListener.AssertUiEnabled should default to `true` off Windows, even if/when a GUI is never shown, because DefaultTraceListener.AssertUiEnabled is in fact meaningless (it's not the sole control over whether a GUI is shown).

Which really means the docs are misleading. :-)

	http://msdn.microsoft.com/en-us/library/system.diagnostics.defaulttracelistener.assertuienabled(v=vs.110).aspx

It's entirely possible, as we can now see, for "user interface mode" to be enabled, yet still not actually display a GUI when Fail() is invoked. This possibility is not noted at all in the documentation, afaict.

 - Jon



More information about the Mono-list mailing list