Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is and how to fix System.TypeInitializationException error?

private static void Main(string[] args) {     string str = null;     Logger.InitUserLogWithRotation();            // <--- error occur     ... } 

When I build project, it has no error. But When I execute it, it always aborted.

I tried to debug project , but System.TypeInitializationException error occurred at first line.

I've already tried to googling , yet found no solution.

It seems like any variable initialize code is wrong , but can't find it.

Please help me. I'm new to C#.

Thanks.

※ Here is Logger Class Code

public class Logger {     private static int HDLOG_PRIORITY_DEBUG = 4;     private static int HDLOG_PRIORITY_ERROR = 1;     private static int HDLOG_PRIORITY_FATAL = 0;     private static int HDLOG_PRIORITY_INFO = 3;     private static int HDLOG_PRIORITY_WARNING = 2;     public static int LOG_LEVEL_DEBUG = 4;     public static int LOG_LEVEL_ERROR = 2;     public static int LOG_LEVEL_FATAL = 1;     public static int LOG_LEVEL_INFO = 5;     public static int LOG_LEVEL_WARNING = 3;     private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");     private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");     private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);     private static bool s_consoleLogging = false;     private static FileStream s_fileStream;     public static HdLoggerCallback s_HdLoggerCallback;     private static string s_logDir = null;     private static string s_logFileName = "XXXX";     private static string s_logFilePath = null;     public static int s_logFileSize = 0xa00000;     private static bool s_loggerInited = false;     private static string s_logLevels = null;     private static int s_logRotationTime = 0x7530;     private static string s_logStringDebug = "DEBUG";     private static string s_logStringError = "ERROR";     private static string s_logStringFatal = "FATAL";     private static string s_logStringInfo = "INFO";     private static string s_logStringWarning = "WARNING";     private static int s_processId = -1;     private static string s_processName = "Unknown";     private static object s_sync = new object();     public static int s_totalLogFileNum = 5;     private static TextWriter writer = Console.Error;      private static void Close()     {         if (!s_consoleLogging)         {             writer.Close();             s_fileStream.Dispose();             writer.Dispose();         }     }      public static void Debug(string msg)     {         Debug("{0}", new object[] { msg });     }      public static void Debug(string fmt, params object[] args)     {         Print(LOG_LEVEL_DEBUG, s_processName, fmt, args);     }      private static void DoLogRotation()     {     Label_0000:         Thread.Sleep(s_logRotationTime);         try         {             lock (s_sync)             {                 FileInfo info = new FileInfo(s_logFilePath);                 if (info.Length >= s_logFileSize)                 {                     string destFileName = s_logFilePath + ".1";                     string path = s_logFilePath + "." + s_totalLogFileNum;                     if (File.Exists(path))                     {                         File.Delete(path);                     }                     for (int i = s_totalLogFileNum - 1; i >= 1; i--)                     {                         string str3 = s_logFilePath + "." + i;                         string str4 = s_logFilePath + "." + (i + 1);                         if (File.Exists(str3))                         {                             File.Move(str3, str4);                         }                     }                     File.Move(s_logFilePath, destFileName);                 }             }             goto Label_0000;         }         catch (Exception)         {             goto Label_0000;         }     }      public static void Error(string msg)     {         Error("{0}", new object[] { msg });     }      public static void Error(string fmt, params object[] args)     {         Print(LOG_LEVEL_ERROR, s_processName, fmt, args);     }      public static void Fatal(string msg)     {         Fatal("{0}", new object[] { msg });     }      public static void Fatal(string fmt, params object[] args)     {         Print(LOG_LEVEL_FATAL, s_processName, fmt, args);     }      private static string GetLogDir(bool userSpecificLog)     {         string str;         if (s_logDir != null)         {             return s_logDir;         }         try         {             if (userSpecificLog)             {                 str = Path.Combine(s_bstUserDataDir, "Logs");             }             else             {                 str = (string) Registry.LocalMachine.OpenSubKey(@"Software\XXXX").GetValue("LogDir");             }         }         catch (Exception)         {             str = Path.Combine(s_bstUserDataDir, "Logs");         }         s_logDir = str;         return str;     }      private static string GetPrefix(string tag, string logLevel)     {         int managedThreadId = Thread.CurrentThread.ManagedThreadId;         DateTime now = DateTime.Now;         return string.Format("{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}.{6:D3} {7}:{8:X8} ({9}). {10}: ", new object[] { now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, now.Millisecond, s_processId, managedThreadId, tag, logLevel });     }      public static TextWriter GetWriter()     {         return new Writer(delegate (string msg) {             Print(msg);         });     }      private static void HdLogger(int prio, uint tid, string tag, string msg)     {         int level = 0;         if (prio == HDLOG_PRIORITY_FATAL)         {             level = LOG_LEVEL_FATAL;         }         else if (prio == HDLOG_PRIORITY_ERROR)         {             level = LOG_LEVEL_ERROR;         }         else if (prio == HDLOG_PRIORITY_WARNING)         {             level = LOG_LEVEL_WARNING;         }         else if (prio == HDLOG_PRIORITY_INFO)         {             level = LOG_LEVEL_INFO;         }         else if (prio == HDLOG_PRIORITY_DEBUG)         {             level = LOG_LEVEL_DEBUG;         }         Print(level, tag, "{0:X8}: {1}", new object[] { tid, msg });     }      public static void Info(string msg)     {         Info("{0}", new object[] { msg });     }      public static void Info(string fmt, params object[] args)     {         Print(LOG_LEVEL_INFO, s_processName, fmt, args);     }      public static void InitConsoleLog()     {         InitLog("-", true, false);     }      public static void InitLog(string logFileName, bool userSpecificLog, bool doLogRotation)     {         s_loggerInited = true;         s_HdLoggerCallback = new HdLoggerCallback(Logger.HdLogger);         s_processId = Process.GetCurrentProcess().Id;         s_processName = Process.GetCurrentProcess().ProcessName;         if (logFileName == "-")         {             writer = Console.Error;             s_consoleLogging = true;         }         else         {             if (logFileName == null)             {                 logFileName = s_logFileName;             }             if (userSpecificLog)             {                 logFileName = logFileName + "Users";             }             string logDir = GetLogDir(userSpecificLog);             string str2 = string.Format(@"{0}\{1}.log", logDir, logFileName);             if (!Directory.Exists(logDir))             {                 Directory.CreateDirectory(logDir);             }             s_logFilePath = str2;             LogLevelsInit();             lock (s_sync)             {                 Open();             }             if (doLogRotation)             {                 new Thread(() => DoLogRotation()) { IsBackground = true }.Start();             }         }     }      public static void InitSystemLog()     {         InitLog(null, false, false);     }      public static void InitSystemLogWithRotation()     {         InitLog(null, false, true);     }      public static void InitUserLog()     {         InitLog(null, true, false);     }      public static void InitUserLogWithRotation()     {         InitLog(null, true, true);     }      private static bool IsLogLevelEnabled(string tag, string level)     {         if (s_logLevels == null)         {             return false;         }         return (s_logLevels.StartsWith("ALL") || s_logLevels.Contains((tag + ":" + level).ToUpper()));     }      private static void LogLevelsInit()     {         string name = @"Software\XXXX\Config";         try         {             using (RegistryKey key = Registry.LocalMachine.OpenSubKey(name))             {                 s_logLevels = (string) key.GetValue("DebugLogs");             }         }         catch (Exception)         {             return;         }         if (s_logLevels != null)         {             s_logLevels = s_logLevels.ToUpper();         }     }      private static void Open()     {         if (!s_consoleLogging)         {             if (!s_loggerInited)             {                 InitLog("-", false, false);                 s_loggerInited = true;             }             else             {                 s_fileStream = new FileStream(s_logFilePath, FileMode.Append, FileAccess.Write, FileShare.Delete | FileShare.ReadWrite);                 writer = new StreamWriter(s_fileStream, Encoding.UTF8);             }         }     }      public static void Print(string msg)     {         Print("{0}", new object[] { msg });     }      public static void Print(string fmt, params object[] args)     {         Print(LOG_LEVEL_INFO, s_processName, fmt, args);     }      public static void Print(int level, string tag, string fmt, params object[] args)     {         string str = "UNKNOWN";         if (level == LOG_LEVEL_FATAL)         {             str = s_logStringFatal;         }         else if (level == LOG_LEVEL_ERROR)         {             str = s_logStringError;         }         else if (level == LOG_LEVEL_WARNING)         {             str = s_logStringWarning;         }         else if (level == LOG_LEVEL_INFO)         {             str = s_logStringInfo;         }         else if (level == LOG_LEVEL_DEBUG)         {             str = s_logStringDebug;         }         if ((level != LOG_LEVEL_DEBUG) || IsLogLevelEnabled(tag, str))         {             lock (s_sync)             {                 Open();                 writer.WriteLine(GetPrefix(tag, str) + fmt, args);                 writer.Flush();                 Close();             }         }     }      public static void SetLogDir(string logDir)     {         s_logDir = logDir;     }      public static void Warning(string msg)     {         Warning("{0}", new object[] { msg });     }      public static void Warning(string fmt, params object[] args)     {         Print(LOG_LEVEL_WARNING, s_processName, fmt, args);     }      public delegate void HdLoggerCallback(int prio, uint tid, string tag, string msg);      public class Writer : TextWriter     {         private WriteFunc writeFunc;          public Writer(WriteFunc writeFunc)         {             this.writeFunc = writeFunc;         }          public override void WriteLine(string msg)         {             this.writeFunc(msg);         }          public override void WriteLine(string fmt, object obj)         {             this.writeFunc(string.Format(fmt, obj));         }          public override void WriteLine(string fmt, object[] objs)         {             this.writeFunc(string.Format(fmt, objs));         }          public override System.Text.Encoding Encoding         {             get             {                 return System.Text.Encoding.UTF8;             }         }          public delegate void WriteFunc(string msg);     } } 
like image 231
bTagTiger Avatar asked Sep 24 '13 18:09

bTagTiger


2 Answers

Whenever a TypeInitializationException is thrown, check all initialization logic of the type you are referring to for the first time in the statement where the exception is thrown - in your case: Logger.

Initialization logic includes: the type's static constructor (which - if I didn't miss it - you do not have for Logger) and field initialization.

Field initialization is pretty much "uncritical" in Logger except for the following lines:

private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX"); private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData"); private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); 

s_commonAppData is null at the point where Path.Combine(s_commonAppData, "XXXX"); is called. As far as I'm concerned, these initializations happen in the exact order you wrote them - so put s_commonAppData up by at least two lines ;)

like image 100
olydis Avatar answered Sep 25 '22 14:09

olydis


System.TypeInitializationException happens when the code that gets executed during the process of loading the type throws an exception.

When .NET loads the type, it must prepare all its static fields before the first time that you use the type. Sometimes, initialization requires running code. It is when that code fails that you get a System.TypeInitializationException.

In your specific case, the following three static fields run some code:

private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX"); private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData"); private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); 

Note that s_bstCommonAppData depends on s_commonAppData, but it is declared ahead of its dependency. Therefore, the value of s_commonAppData is null at the time that the Path.Combine is called, resulting in ArgumentNullException. Same goes for the s_bstUserDataDir and s_bstCommonAppData: they are declared in reverse order to the desired order of initialization.

Re-order the lines to fix this problem:

private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX"); private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData"); 
like image 27
Sergey Kalinichenko Avatar answered Sep 21 '22 14:09

Sergey Kalinichenko