As written in the second edit I figured out the problem being the eventlog being full when trying to write to it. I log A LOT and the default behavior of an EventLog is MaximumKilobytes of 512 or so and retaining entries newer than 7 days. I changed the configuration so that the MaximumKilobytes is equal to 25 Megabytes and overwriting entries as needed.
Unhandled exception in Windows Service when using catch(Exception)
-
27-06-2022 - |
Pregunta
I am having a very frustrating problem. I am writting a Windows Service, which acts like a TCPServer (I am not sure about the technical term, but the service handles communications via tcp between a set of clients).
My problem is that the service crashes randomly (at least I don't know what causes the exception) and the windows application log contains a VsJITDebugger (EventID 4096) error message saying:
An unhandled win32 exception occurred in SDUNoteTCPServerService.exe [1028]. Just-In- Time debugging this exception failed with the following error: Debugger could not be started because no user is logged on.
I am not a 100 % sure what the VsJITDebugger is, but as far as I have found out by googling the VsJITDebugger is some kind of tool that uses Visual Studio to clarify unhandled exceptions. Sometimes I also see the following .Net Runtime (EventID: 1026) error message just before the VsJITDebugger error message:
Application: SDUNoteTCPServerService.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.ComponentModel.Win32Exception Stack: at System.Diagnostics.EventLogInternal.InternalWriteEvent(UInt32, UInt16, System.Diagnostics.EventLogEntryType, System.String[], Byte[], System.String) at System.Diagnostics.EventLogInternal.WriteEntry(System.String, System.Diagnostics.EventLogEntryType, Int32, Int16, Byte[]) at System.Diagnostics.EventLog.WriteEntry(System.String, System.Diagnostics.EventLogEntryType, Int32) at TCPServer.TCPServerListener+AsynchronousSocketListener.WriteCustomSocketObjectMessagesToLog (System.String, System.Diagnostics.EventLogEntryType, Int32) at TCPServer.TCPServerListener+CustomSocketObject.SendMessageToClientThread() at System.Threading.ThreadHelper.ThreadStart_Context(System.Object) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) at System.Threading.ThreadHelper.ThreadStart()
As stated in the .Net Runtime error message the unhandled error is thrown when I try to write details about the caught exception in an EventLog. The exception is always thrown in the callback function of a socket's BeginReceive method.
I don't know why this exception is crashing the service in the first place, because I am catching generic exceptions using try{}catch(Exception) in the Socket.BeginReceive method's callback function, but I am not able to extract any information about the caught exception, because of this unhandled exception getting thrown.
Any ideas what the problem might be? All replies are appreciated.
Note: The service is running on a Windows Server 2003 (SP2). Visual Studio 2008 is installed.
Edit: The WriteCustomSocketObjectMessagesToLog looks like this (the eventlog object is a property of the AsynchronousSocketListener class):
private void WriteExceptionToLog(string customstartmessage, Exception ex) { try { eventlog.WriteEntry(customstartmessage, EventLogEntryType.Error); eventlog.WriteEntry(ex.Message, EventLogEntryType.Error, 5); eventlog.WriteEntry(ex.Source, EventLogEntryType.Error, 5); eventlog.WriteEntry(ex.StackTrace, EventLogEntryType.Error, 5); } catch (Exception) { eventlog.WriteEntry("Failed reporting exception", EventLogEntryType.Error); } }
Edit 2:
I figured out what the problem is. The eventlog is reported full. No wonder I am not able to write to it then. I found the problem by converting the class library to a console application. I also did this when I started writting the TCPServer class, but back then I wrote errors to Console using the WriteLine method. This time the console application writes to the created eventlog and the unhandled exception was written to Console (I don't if this is default behavior of a console application because I have not done any coding doing this). The unhandled error in my Windows Service is most probably this:
Unhandled Exception: System.ComponentModel.Win32Exception: The event log file is full at System.Diagnostics.EventLogInternal.InternalWriteEvent(UInt32 eventID, UInt16 category, EventLogEntryType type, String[] strings, Byte[] rawData, String currentMachineName) at System.Diagnostics.EventLogInternal.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData) at System.Diagnostics.EventLog.WriteEntry(String message) at TCPServer.Program.Main(String[] args)
Now I just need to handle this probably. What would be the better solution to handle this error? Saving and emptying the eventlog programmatically everytime the error is thrown? Increase the eventlog size unlimited (is this possible and a good idea?)? Any other suggestions?
Solución
Otros consejos
Define a handler for your AppDomain UnhandledException event:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
void MyHandler(object sender, UnhandledExceptionEventArgs e)
{
// See the exception context here using e.ExceptionObject
}
If you want to catch the exception you need to add an exception handler in AsynchronousSocketListener.WriteCustomSocketObjectMessagesToLog
. The AsynchronousSocketListener
class is nested inside the TCPServerListener
in the TCPServer
namespace. I assume this class is something you or your organization has implemented.
Unfortunately, the exception is thrown in some code that tries to write to the event log so catching the exception and trying to log it may be somewhat hard if the root cause of the exception is say memory exhaustion.
Looking into the .NET 4.0 source code for InternalWriteEvent
in the System.Diagnostics.EventLogInternal
class there seems to be only one place where a Win32Exception
can be thrown and that is if the call to ReportEvent
function fails.
The Win32Exception
will contain a Windows error code. According to the ReportEvent
documentation four error codes are possible:
- ERROR_INVALID_PARAMETER (87)
- ERROR_NOT_ENOUGH_MEMORY (8)
- RPC_S_INVALID_BOUND (1734)
- RPC_X_BAD_STUB_DATA (1783)
- There is also the possibility of other error codes
Discovering the error code of the Win32Exception
should hopefully help you understand the source of your problem.