[Mono-dev] AppDomain.ProcessExit event firing too early?

Luca kronos.it at gmail.com
Sat Jan 21 15:36:56 EST 2006


Hi,
I'm developing a cross-platform application which uses Log4NET for its
logging. The main thread of the application just parses the config file,
spawns additional foreground threads and then exits (basicaly it's a
server).

Under Linux, using Mono I see a strange behaviour when the main thread
terminates: the logger doesn't work anymore. Note that the other
foreground threads are still running so the application is not
terminated.

What is happening is that delegates registered on the ProcessExit event
are called as soon as the main thread exits, even when other threads
are still active.

This is small testcase that exhibits the same problem:

using System;
using System.Threading;

[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension="log4net.xml")]

class Class1 {
	private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(Class1));
		
	static void Test() {
		/* Let the main thread die */
		Thread.Sleep(1000);
		log.Debug("Class1::Test()");
	}

	static void OnProcessExit(object sender, EventArgs a) {
		Console.WriteLine("OnProcessExit");
	}
	
	static void Main() {
		AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit);
		Thread thread = new Thread(new ThreadStart(Test));
			
		log.Debug("Test message");

		thread.Start();
	}
}

Using the following configuration:

<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="true">
	<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
		<layout type="log4net.Layout.PatternLayout">
			<conversionPattern value="%timestamp [%thread] %-5level %logger - %message%newline" />
		</layout>
	</appender>
	<root>
		<level value="DEBUG" />
		<appender-ref ref="ConsoleAppender" />
	</root>
</log4net>


The output is the following:

log4net: XmlHierarchyConfigurator: Configuration update mode [Merge].
log4net: XmlHierarchyConfigurator: Logger [root] Level string is [DEBUG].
log4net: XmlHierarchyConfigurator: Logger [root] level set to [name="DEBUG",value=30000].
log4net: XmlHierarchyConfigurator: Loading Appender [ConsoleAppender] type: [log4net.Appender.ConsoleAppender]
log4net: PatternParser: Converter [message] Option [] Format [min=-1,max=2147483647,leftAlign=False]
log4net: PatternParser: Converter [newline] Option [] Format [min=-1,max=2147483647,leftAlign=False]
log4net: XmlHierarchyConfigurator: Setting Property [ConversionPattern] to String value [%timestamp [%thread] %-5level %logger - %message%newline]
log4net: PatternParser: Converter [timestamp] Option [] Format [min=-1,max=2147483647,leftAlign=False]
log4net: PatternParser: Converter [literal] Option [ [] Format [min=-1,max=2147483647,leftAlign=False]
log4net: PatternParser: Converter [thread] Option [] Format [min=-1,max=2147483647,leftAlign=False]
log4net: PatternParser: Converter [literal] Option [] ] Format [min=-1,max=2147483647,leftAlign=False]
log4net: PatternParser: Converter [level] Option [] Format [min=5,max=2147483647,leftAlign=True]
log4net: PatternParser: Converter [literal] Option [ ] Format [min=-1,max=2147483647,leftAlign=False]
log4net: PatternParser: Converter [logger] Option [] Format [min=-1,max=2147483647,leftAlign=False]
log4net: PatternParser: Converter [literal] Option [ - ] Format [min=-1,max=2147483647,leftAlign=False]
log4net: PatternParser: Converter [message] Option [] Format [min=-1,max=2147483647,leftAlign=False]
log4net: PatternParser: Converter [newline] Option [] Format [min=-1,max=2147483647,leftAlign=False]
log4net: XmlHierarchyConfigurator: Setting Property [Layout] to object [log4net.Layout.PatternLayout]
log4net: XmlHierarchyConfigurator: Created Appender [ConsoleAppender]
log4net: XmlHierarchyConfigurator: Adding appender named [ConsoleAppender] to logger [root].
log4net: XmlHierarchyConfigurator: Hierarchy Threshold []
1505 [-1212848448] DEBUG Class1 - Test message
log4net: Hierarchy: Shutdown called on Hierarchy [log4net-default-repository] <- !!!
OnProcessExit <- !!!
log4net: Logger: No appenders could be found for logger [Class1] repository [log4net-default-repository]
log4net: Logger: Please initialize the log4net system properly.
log4net: Logger:    Current AppDomain context information: 
log4net: Logger:       BaseDirectory   : /tmp/log/TestLog1/
log4net: Logger:       FriendlyName    : Class1.exe
log4net: Logger:       DynamicDirectory: 

As you can see OnProcessExit is called too early, log4net shuts down the
loggers and other threads are unable to use them.

kronos:/tmp/log/TestLog1$ mono --version
Mono JIT compiler version 1.1.13.1, (C) 2002-2005 Novell, Inc and Contributors. www.mono-project.com
        TLS:           normal
        GC:            Included Boehm (with typed GC)
        SIGSEGV      : normal
                        
Note that the same test-case works correctly under MS Windows (compiled
with VS.NET 2003).

Luca
-- 
Home: http://kronoz.cjb.net
Runtime error 6D at f000:a12f : user incompetente



More information about the Mono-devel-list mailing list