1//
2// Copyright (c) Microsoft. All rights reserved.
3// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4//
5
6//----------------------------------------------------------
7// Logging.h - Common logging and console output infrastructure
8//----------------------------------------------------------
9#ifndef _Logging
10#define _Logging
11
12//
13// General purpose logging macros
14//
15
16#define LogMessage(level, ...) Logger::LogPrintf(__func__, __FILE__, __LINE__, level, __VA_ARGS__)
17
18#define LogError(...) LogMessage(LOGLEVEL_ERROR, __VA_ARGS__)
19#define LogWarning(...) LogMessage(LOGLEVEL_WARNING, __VA_ARGS__)
20#define LogMissing(...) LogMessage(LOGLEVEL_MISSING, __VA_ARGS__)
21#define LogInfo(...) LogMessage(LOGLEVEL_INFO, __VA_ARGS__)
22#define LogVerbose(...) LogMessage(LOGLEVEL_VERBOSE, __VA_ARGS__)
23#define LogDebug(...) LogMessage(LOGLEVEL_DEBUG, __VA_ARGS__)
24
25#define LogIssue(issue, msg, ...) IssueLogger::LogIssueHelper(__FUNCTION__, __FILE__, __LINE__, issue, msg, __VA_ARGS__)
26
27// Captures the exception message before throwing so we can log it at the point of occurrence
28#define LogException(exCode, msg, ...) \
29 do \
30 { \
31 Logger::LogExceptionMessage(__FUNCTION__, __FILE__, __LINE__, exCode, msg, __VA_ARGS__); \
32 ThrowException(exCode, msg, __VA_ARGS__); \
33 } while (0)
34
35// These are specified as flags so subsets of the logging functionality can be enabled/disabled at once
36enum LogLevel : UINT32
37{
38 LOGLEVEL_ERROR = 0x00000001, // Internal fatal errors that are non-recoverable
39 LOGLEVEL_WARNING = 0x00000002, // Internal conditions that are unusual, but not serious
40 LOGLEVEL_MISSING = 0x00000004, // Failures to due to missing JIT-EE details
41 LOGLEVEL_ISSUE = 0x00000008, // Issues found with the JIT, e.g. asm diffs, asserts
42 LOGLEVEL_INFO = 0x00000010, // Notifications/summaries, e.g. 'Loaded 5 Jitted 4 FailedCompile 1'
43 LOGLEVEL_VERBOSE = 0x00000020, // Status messages, e.g. 'Jit startup took 151.12ms'
44 LOGLEVEL_DEBUG = 0x00000040 // Detailed output that's only useful for SuperPMI debugging
45};
46
47// Preset log level combinations
48enum LogLevelMask : UINT32
49{
50 LOGMASK_NONE = 0x00000000,
51 LOGMASK_DEFAULT = (LOGLEVEL_DEBUG - 1), // Default is essentially "enable everything except debug"
52 LOGMASK_ALL = 0xffffffff
53};
54
55//
56// Manages the SuperPMI logging subsystem, including both file-based logging and logging to the console.
57//
58class Logger
59{
60private:
61 static bool s_initialized;
62 static UINT32 s_logLevel;
63 static HANDLE s_logFile;
64 static char* s_logFilePath;
65 static CRITICAL_SECTION s_critSec;
66
67public:
68 static void Initialize();
69 static void Shutdown();
70
71 static void OpenLogFile(char* logFilePath);
72 static void CloseLogFile();
73
74 static UINT32 ParseLogLevelString(const char* specifierStr);
75 static void SetLogLevel(UINT32 logLevelMask)
76 {
77 s_logLevel = logLevelMask;
78 }
79 static UINT32 GetLogLevel()
80 {
81 return s_logLevel;
82 }
83
84 // Return true if all specified log levels are enabled.
85 static bool IsLogLevelEnabled(UINT32 logLevelMask)
86 {
87 return (logLevelMask & GetLogLevel()) == logLevelMask;
88 }
89
90 static void LogPrintf(const char* function, const char* file, int line, LogLevel level, const char* msg, ...);
91 static void LogVprintf(
92 const char* function, const char* file, int line, LogLevel level, va_list argList, const char* msg);
93 static void LogExceptionMessage(
94 const char* function, const char* file, int line, DWORD exceptionCode, const char* msg, ...);
95};
96
97enum IssueType
98{
99 ISSUE_ASSERT,
100 ISSUE_ASM_DIFF
101};
102
103//
104// JIT issues have more granularity than other types of log messages. The logging of issues is abstracted
105// from the normal logger to reflect this. It also will enable us to track things specific to JIT issues,
106// like statistics on issues that were found during a run.
107//
108class IssueLogger
109{
110public:
111 static void LogIssueHelper(const char* function, const char* file, int line, IssueType issue, const char* msg, ...);
112};
113
114#endif
115