Bug 9520 - Dns.GetHostName() fails in the standard mono 3.0.3 (OSX 10.8.2)
Summary: Dns.GetHostName() fails in the standard mono 3.0.3 (OSX 10.8.2)
Status: NEW
Alias: None
Product: Class Libraries
Classification: Mono
Component: System (show other bugs)
Version: unspecified
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-01-12 22:11 UTC by Jonathan Shore
Modified: 2013-10-21 21:32 UTC (History)
3 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
proposed patch for this bug (1.43 KB, application/octet-stream)
2013-02-20 16:19 UTC, Jonathan Shore
Details

Description Jonathan Shore 2013-01-12 22:11:32 UTC
The new packaged OSX mono runtime is throwing an exception when trying to determine the hostname, with the following code:

    var localhost = Dns.GetHostName();

The exception throws is as follows:

System.Configuration.ConfigurationErrorsException: Error Initializing the configuration system. ---> System.Exception: The 'ExeConfigFilename' argument cannot be null.
  at System.Configuration.ExeConfigurationHost.CheckFileMap (ConfigurationUserLevel level, System.Configuration.ExeConfigurationFileMap map) [0x0002b] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System.Configuration/System.Configuration/InternalConfigurationHost.cs:293
  at System.Configuration.ExeConfigurationHost.InitForConfiguration (System.String& locationSubPath, System.String& configPath, System.String& locationConfigPath, IInternalConfigRoot root, System.Object[] hostInitConfigurationParams) [0x00036] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System.Configuration/System.Configuration/InternalConfigurationHost.cs:338
  at System.Configuration.InternalConfigurationSystem.InitForConfiguration (System.String& locationConfigPath, System.String& parentConfigPath, System.String& parentLocationConfigPath) [0x00000] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System.Configuration/System.Configuration/InternalConfigurationFactory.cs:67
  at System.Configuration.Configuration..ctor (System.Configuration.InternalConfigurationSystem system, System.String locationSubPath) [0x0001f] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System.Configuration/System.Configuration/Configuration.cs:86
  at System.Configuration.InternalConfigurationFactory.Create (System.Type typeConfigHost, System.Object[] hostInitConfigurationParams) [0x0000e] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System.Configuration/System.Configuration/InternalConfigurationFactory.cs:42
  at System.Configuration.ConfigurationManager.OpenExeConfigurationInternal (ConfigurationUserLevel userLevel, System.Reflection.Assembly calling_assembly, System.String exePath) [0x00124] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System.Configuration/System.Configuration/ConfigurationManager.cs:119
  at System.Configuration.ClientConfigurationSystem.get_Configuration () [0x00011] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System.Configuration/System.Configuration/ClientConfigurationSystem.cs:51
  --- End of inner exception stack trace ---
  at System.Configuration.ClientConfigurationSystem.get_Configuration () [0x00025] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System.Configuration/System.Configuration/ClientConfigurationSystem.cs:54
  at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection (System.String configKey) [0x00000] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System.Configuration/System.Configuration/ClientConfigurationSystem.cs:63
  at System.Configuration.ConfigurationManager.GetSection (System.String sectionName) [0x00006] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System.Configuration/System.Configuration/ConfigurationManager.cs:162
  at System.Net.Sockets.Socket.CheckProtocolSupport () [0x0003c] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System/System.Net.Sockets/Socket_2_1.cs:798
  at System.Net.Sockets.Socket..cctor () [0x0000c] in /private/tmp/source/bockbuild/profiles/mono-mac-release/build-root/mono-3.0.3/_build/mono-3.0.3.git/mcs/class/System/System.Net.Sockets/Socket_2_1.cs:778

This mac is connected to the internet and also has a proper hostname:

yume:Libraries jshore$ hostname
yume

Somehow the protocol support check is failing.
Comment 1 Jonathan Shore 2013-01-13 07:13:40 UTC
I should note that I had this behavior from an application which is linking to C# (libmono-2.0) (i.e. using mono in an embedded fashion).   This aoplication was working in older versions of the VM.

I note that it throws the exception:

    System.Exception: The 'ExeConfigFilename' argument cannot be null.

within the ExeConfigurationHost class, CheckFileMap () method.

I am guessing it is trying to find the exe configuration file.   Am not sure why this mapping is passed in as null.
Comment 2 Jonathan Shore 2013-01-13 07:44:49 UTC
I noticed that someone else has the same problem and commented on github.   The following was suggested to the other respondent by baulig:

-----
When taking the code path from your stack trace, the only way you could possibly get there with ExeConfigFileName == null is if AppDomain.CurrentDomain.SetupInformation.ConfigurationFile == null - and the only way of achieving that is calling the unmanaged mono_domain_create_appdomain (char *friendly_name, char *configuration_file) with a NULL argument.

It's normally set in mono_runtime_exec_main() by appending ".config" to the assembly filename.

I think FreeSWITCH should call mono_domain_create_appdomain() to create a domain and specify the configuration file. The file does not need to exist, but you have to tell the configuration system where to look for it.

As a workaround, we could also add a check here and set an arbitrary name like "app.config" if AppDomain.CurrentDomain.SetupInformation.ConfigurationFile == null.


-----
Here is my followup comment there:

"I am having the same problem with an application that embeds mono. This application has been working fine in prior versions. There is no explicit call to: mono_domain_create_appdomain().

Rather the following is done:

_domain = mono_jit_init (bootassembly);
_core = mono_domain_assembly_open (_domain, bootassembly);
mono_config_parse (NULL);
...

bootassembly is the path the the main assembly to be used. I would have thought that mono_jit_init() would create an AppDomain and set the appropriate structure.

Finally, this is the approach outlined in http://www.mono-project.com/Embedding_Mono. Suggest doing the workaround as suggested above or making sure that the above embedded mono C-api calls create the app domain with the app domain name filled in."
Comment 3 Jonathan Shore 2013-01-13 08:04:06 UTC
mono_jit_init() eventually creates the AppDomain with:

    mono_init_from_assembly (filename, filename);

which calls:

    mono_init_internal (domain_name, filename, NULL);

which sets up the domain structures, etc.   It seems to me that these calls are probably not setting up the configuration location.  

In any case, changing the C# configuration code to be resilient is probably the right thing to do.
Comment 4 Jonathan Shore 2013-02-20 16:19:56 UTC
Created attachment 3430 [details]
proposed patch for this bug

I have a simple patch that detects a configuration exception (if the configuraton is not present) and continues on the the next ipv6 test.
Comment 5 Andres G. Aragoneses 2013-03-12 20:17:20 UTC
What's the exception raised that you're catching in the catch block? It would be better to be specific, not just catch the generic "Exception". Also, you have some spaces, when you should be using tabs. And cannot the try-catch block focus on a smaller piece of code? Surely the exception you noticed only happened in one of those lines.
Comment 6 Jonathan Shore 2013-03-12 20:52:31 UTC
The exception is:  System.Configuration.ConfigurationErrorsException.  However this involves adding a library dependency if I recall.  I did not know what to change in order to add this additional library into the class build.  I don't understand the build process for this.  Appreciate your adjustments, kindly.

Both config = (SettingsSection) System.Configuration.ConfigurationManager.GetSection()  AND  NetConfig config = System.Configuration.ConfigurationSettings.GetConfig(() can throw an exception.

Could double up a try/catch or just have one across these 2 calls, whichever you prefer.   There are only 4 real lines of code here.
Comment 7 Andres G. Aragoneses 2013-03-12 20:56:10 UTC
Oh good point about the dependency. I guess you can then use the generic catch(Exception), but then put a comment saying that the actual exception is ConfigurationErrorsException.

BTW, if you add a unit test (that passes on .NET and fails on Mono without the bugfix) to the mono test suite in your patch, and you post the patch as a pull request on github, it will have higher chances to be included upstream.
Comment 8 Jonathan Shore 2013-03-13 07:26:37 UTC
Thanks for the advice.  The unit test cannot be done as a C# test.  The problem occurs only with embedded applications, because embedded applications have no application config set up.

Regardless, the expected behavior of the config calls is that they can emit the above exception.  We should be guarding against that and allow this static initializer to proceed.

What would you recommend in getting this in?   This bug has been reported on discussions in github  (by another developer as well), but is hard to show as a unit test, unless unit tests include the much more compllex, embedded applications.
Comment 9 Chris 2013-10-21 21:32:32 UTC
FYI if you call mono_domain_create_appdomain() yourself, you DO have to have a valid config file with a <configuration/> block, or you will get errors saying the ApplicationBase must be set when the configuration manager tries to access various settings.

Being that this whole issue breaks pretty much anything using network calls, the embedding docs should be updated until this gets fixed.  I wasted a good amount of time on this basically because of bad documentation.

Note You need to log in before you can comment on or make changes to this bug.