From 296cf8d77f157f9ad73b00c176b0d439519084d9 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 6 Apr 2017 23:54:36 -0700 Subject: [PATCH] Merge pull request dotnet/corert#3243 from dotnet/nmirror Merge nmirror to master Signed-off-by: dotnet-bot --- .../Interop/Unix/System.Native/Interop.SysLog.cs | 58 ++++ .../Windows/Kernel32/Interop.OutputDebugString.cs | 14 + .../shared/System.Private.CoreLib.Shared.projitems | 3 + src/mscorlib/shared/System/Diagnostics/Debug.cs | 323 +++++++++++++++++++++ 4 files changed, 398 insertions(+) create mode 100644 src/mscorlib/shared/Interop/Unix/System.Native/Interop.SysLog.cs create mode 100644 src/mscorlib/shared/Interop/Windows/Kernel32/Interop.OutputDebugString.cs create mode 100644 src/mscorlib/shared/System/Diagnostics/Debug.cs diff --git a/src/mscorlib/shared/Interop/Unix/System.Native/Interop.SysLog.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.SysLog.cs new file mode 100644 index 0000000..6b6a74b --- /dev/null +++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.SysLog.cs @@ -0,0 +1,58 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Sys + { + internal enum SysLogPriority : int + { + // Priorities + LOG_EMERG = 0, /* system is unusable */ + LOG_ALERT = 1, /* action must be taken immediately */ + LOG_CRIT = 2, /* critical conditions */ + LOG_ERR = 3, /* error conditions */ + LOG_WARNING = 4, /* warning conditions */ + LOG_NOTICE = 5, /* normal but significant condition */ + LOG_INFO = 6, /* informational */ + LOG_DEBUG = 7, /* debug-level messages */ + // Facilities + LOG_KERN = (0<<3), /* kernel messages */ + LOG_USER = (1<<3), /* random user-level messages */ + LOG_MAIL = (2<<3), /* mail system */ + LOG_DAEMON = (3<<3), /* system daemons */ + LOG_AUTH = (4<<3), /* authorization messages */ + LOG_SYSLOG = (5<<3), /* messages generated internally by syslogd */ + LOG_LPR = (6<<3), /* line printer subsystem */ + LOG_NEWS = (7<<3), /* network news subsystem */ + LOG_UUCP = (8<<3), /* UUCP subsystem */ + LOG_CRON = (9<<3), /* clock daemon */ + LOG_AUTHPRIV = (10<<3), /* authorization messages (private) */ + LOG_FTP = (11<<3), /* ftp daemon */ + // Between FTP and Local is reserved for system use + LOG_LOCAL0 = (16<<3), /* reserved for local use */ + LOG_LOCAL1 = (17<<3), /* reserved for local use */ + LOG_LOCAL2 = (18<<3), /* reserved for local use */ + LOG_LOCAL3 = (19<<3), /* reserved for local use */ + LOG_LOCAL4 = (20<<3), /* reserved for local use */ + LOG_LOCAL5 = (21<<3), /* reserved for local use */ + LOG_LOCAL6 = (22<<3), /* reserved for local use */ + LOG_LOCAL7 = (23<<3), /* reserved for local use */ + } + + /// + /// Write a message to the system logger, which in turn writes the message to the system console, log files, etc. + /// See man 3 syslog for more info + /// + /// + /// The OR of a priority and facility in the SysLogPriority enum to declare the priority and facility of the log entry + /// + /// The message to put in the log entry + /// Like printf, the argument is passed to the variadic part of the C++ function to wildcards in the message + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_SysLog")] + internal static extern void SysLog(SysLogPriority priority, string message, string arg1); + } +} diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.OutputDebugString.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.OutputDebugString.cs new file mode 100644 index 0000000..8da50ff --- /dev/null +++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.OutputDebugString.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; + +internal partial class Interop +{ + internal partial class Kernel32 + { + [DllImport(Interop.Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "OutputDebugStringW", ExactSpelling = true)] + internal static extern void OutputDebugString(string message); + } +} diff --git a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems index 344a0c5..914bc9c 100644 --- a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems +++ b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems @@ -34,6 +34,7 @@ + @@ -72,6 +73,7 @@ + @@ -128,6 +130,7 @@ + diff --git a/src/mscorlib/shared/System/Diagnostics/Debug.cs b/src/mscorlib/shared/System/Diagnostics/Debug.cs new file mode 100644 index 0000000..2dfde8d --- /dev/null +++ b/src/mscorlib/shared/System/Diagnostics/Debug.cs @@ -0,0 +1,323 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Do not remove this, it is needed to retain calls to these conditional methods in release builds +#define DEBUG + +namespace System.Diagnostics +{ + /// + /// Provides a set of properties and methods for debugging code. + /// + public static partial class Debug + { + private static readonly object s_lock = new object(); + + public static bool AutoFlush { get { return true; } set { } } + + [ThreadStatic] + private static int s_indentLevel; + public static int IndentLevel + { + get + { + return s_indentLevel; + } + set + { + s_indentLevel = value < 0 ? 0 : value; + } + } + + private static int s_indentSize = 4; + public static int IndentSize + { + get + { + return s_indentSize; + } + set + { + s_indentSize = value < 0 ? 0 : value; + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Close() { } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Flush() { } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Indent() + { + IndentLevel++; + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Unindent() + { + IndentLevel--; + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Print(string message) + { + Write(message); + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Print(string format, params object[] args) + { + Write(string.Format(null, format, args)); + } + + private static readonly object s_ForLock = new Object(); + + [System.Diagnostics.Conditional("DEBUG")] + public static void Assert(bool condition) + { + Assert(condition, string.Empty, string.Empty); + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Assert(bool condition, string message) + { + Assert(condition, message, string.Empty); + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Assert(bool condition, string message, string detailMessage) + { + if (!condition) + { + string stackTrace; + + try + { + stackTrace = Internal.Runtime.Augments.EnvironmentAugments.StackTrace; + } + catch + { + stackTrace = ""; + } + + WriteLine(FormatAssert(stackTrace, message, detailMessage)); + s_ShowAssertDialog(stackTrace, message, detailMessage); + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Fail(string message) + { + Assert(false, message, string.Empty); + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Fail(string message, string detailMessage) + { + Assert(false, message, detailMessage); + } + + private static string FormatAssert(string stackTrace, string message, string detailMessage) + { + string newLine = GetIndentString() + NewLine; + return SR.DebugAssertBanner + newLine + + SR.DebugAssertShortMessage + newLine + + message + newLine + + SR.DebugAssertLongMessage + newLine + + detailMessage + newLine + + stackTrace; + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Assert(bool condition, string message, string detailMessageFormat, params object[] args) + { + Assert(condition, message, string.Format(detailMessageFormat, args)); + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteLine(string message) + { + Write(message + NewLine); + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Write(string message) + { + lock (s_lock) + { + if (message == null) + { + s_WriteCore(string.Empty); + return; + } + if (s_needIndent) + { + message = GetIndentString() + message; + s_needIndent = false; + } + s_WriteCore(message); + if (message.EndsWith(NewLine)) + { + s_needIndent = true; + } + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteLine(object value) + { + WriteLine(value?.ToString()); + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteLine(object value, string category) + { + WriteLine(value?.ToString(), category); + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteLine(string format, params object[] args) + { + WriteLine(string.Format(null, format, args)); + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteLine(string message, string category) + { + if (category == null) + { + WriteLine(message); + } + else + { + WriteLine(category + ":" + message); + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Write(object value) + { + Write(value?.ToString()); + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Write(string message, string category) + { + if (category == null) + { + Write(message); + } + else + { + Write(category + ":" + message); + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void Write(object value, string category) + { + Write(value?.ToString(), category); + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteIf(bool condition, string message) + { + if (condition) + { + Write(message); + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteIf(bool condition, object value) + { + if (condition) + { + Write(value); + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteIf(bool condition, string message, string category) + { + if (condition) + { + Write(message, category); + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteIf(bool condition, object value, string category) + { + if (condition) + { + Write(value, category); + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteLineIf(bool condition, object value) + { + if (condition) + { + WriteLine(value); + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteLineIf(bool condition, object value, string category) + { + if (condition) + { + WriteLine(value, category); + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteLineIf(bool condition, string message) + { + if (condition) + { + WriteLine(message); + } + } + + [System.Diagnostics.Conditional("DEBUG")] + public static void WriteLineIf(bool condition, string message, string category) + { + if (condition) + { + WriteLine(message, category); + } + } + + private static bool s_needIndent; + + private static string s_indentString; + + private static string GetIndentString() + { + int indentCount = IndentSize * IndentLevel; + if (s_indentString?.Length == indentCount) + { + return s_indentString; + } + return s_indentString = new string(' ', indentCount); + } + + private sealed class DebugAssertException : Exception + { + internal DebugAssertException(string message, string detailMessage, string stackTrace) : + base(message + NewLine + detailMessage + NewLine + stackTrace) + { + } + } + + // internal and not readonly so that the tests can swap this out. + internal static Action s_ShowAssertDialog = ShowAssertDialog; + internal static Action s_WriteCore = WriteCore; + } +} -- 2.7.4