From c2ca09dc69380d0f309cb7e15296aea347e780fe Mon Sep 17 00:00:00 2001 From: Sebastien Pouliot Date: Tue, 25 Feb 2020 08:55:37 -0500 Subject: [PATCH] [corefoundation] Fix TypeInitializationException in OSLog (#7962) `Default` property was using a nil-handle which is incorrect since * we don't allow that (this is generally a bad sign) * it does not map to `OS_LOG_DEFAULT` Since `Default` was assigned in the type (static) constructor then the whole type became unusable :( Header `log.h` shows that the right definition requires us to load a field and use it. ``` define OS_LOG_DEFAULT OS_OBJECT_GLOBAL_OBJECT(os_log_t, _os_log_default) ``` While `NULL` can actually be used for disabled (not exposed) by this contradicting (nullability-wise) macro ``` define OS_LOG_DISABLED ((os_log_t _Nonnull)NULL) ``` Also adds unit tests. A more general tests for `.cctor` will be added to introspection tests in a separate PR. Fixes https://github.com/xamarin/xamarin-macios/issues/7959 --- src/CoreFoundation/OSLog.cs | 15 ++++++- .../CoreFoundation/OSLogTest.cs | 40 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 tests/monotouch-test/CoreFoundation/OSLogTest.cs diff --git a/src/CoreFoundation/OSLog.cs b/src/CoreFoundation/OSLog.cs index 1f075acf7b..0c0c16e76b 100644 --- a/src/CoreFoundation/OSLog.cs +++ b/src/CoreFoundation/OSLog.cs @@ -29,7 +29,20 @@ namespace CoreFoundation { [Mac (10,12), iOS (10,0), Watch (3,0), TV (10,0)] [Introduced (PlatformName.MacCatalyst, 13, 0)] public sealed class OSLog : NativeObject { - public static OSLog Default { get; } = new OSLog (IntPtr.Zero, false); + + static OSLog _default; + + public static OSLog Default { + get { + if (_default == null) { + var h = Dlfcn.dlsym (Libraries.System.Handle, "_os_log_default"); + if (h == IntPtr.Zero) + throw new NotSupportedException ("Feature not available on this OS version"); + _default = new OSLog (h, false); + } + return _default; + } + } protected override void Retain () { diff --git a/tests/monotouch-test/CoreFoundation/OSLogTest.cs b/tests/monotouch-test/CoreFoundation/OSLogTest.cs new file mode 100644 index 0000000000..288e4375a9 --- /dev/null +++ b/tests/monotouch-test/CoreFoundation/OSLogTest.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; +using System.Runtime.InteropServices; + +using CoreFoundation; +using Foundation; +using ObjCRuntime; + +using NUnit.Framework; + +namespace MonoTouchFixtures.CoreFoundation { + + [TestFixture] + [Preserve (AllMembers = true)] + public class OSLogTest { + + [TestFixtureSetUp] + public void SetUp () + { + TestRuntime.AssertXcodeVersion (8,0); + } + + [Test] + public void Default () + { + OSLog.Default.Log (OSLogLevel.Default, "monotouch-test / Default / Default"); + // this will show in the application output (e.g. inside VSfM) + } + + [Test] + public void Custom () + { + using (var log = new OSLog ("subsystem", "category")) { + log.Log (OSLogLevel.Error, "monotouch-test / custom / Debug"); + // this will show in the application output (e.g. inside VSfM) + // and also inside Console.app under the simulator/device + } + } + } +}