Marc Bernier
Marc Bernier

Reputation: 2996

Calling Mono exe from C does not find libc

In Ubuntu, I am calling a C# executable from C using Mono (v3.2.8) and the embedded Mono runtime. When I call the exe (.NET 4.5) from the command line (ie, mono testFile.exe), it works fine. However, when I run my C test program, it throws a C# exception:

libc at   at (wrapper managed-to-native) System.Platform:uname (intptr)
  at System.Platform.get_IsMacOS () [0x00000] in <filename unknown>:0
  at System.Net.WebRequest.GetSystemWebProxy () [0x00000] in <filename unknown>:0
  at System.Net.WebRequest.GetDefaultWebProxy () [0x00000] in <filename unknown>:0
  at System.Net.WebRequest.get_DefaultWebProxy () [0x00000] in <filename unknown>:0
  at System.Net.GlobalProxySelection.get_Select () [0x00000] in <filename unknown>:0
  at System.Net.HttpWebRequest..ctor (System.Uri uri) [0x00000] in <filename unknown>:0
  at (wrapper remoting-invoke-with-check) System.Net.HttpWebRequest:.ctor (System.Uri)
  at System.Net.HttpRequestCreator.Create (System.Uri uri) [0x00000] in <filename unknown>:0
  at System.Net.WebRequest.Create (System.Uri requestUri) [0x00000] in <filename unknown>:0
  at System.Net.WebRequest.Create (System.String requestUriString) [0x00000] in <filename unknown>:0
  at MyClass.MainClass.Main (System.String[] args) [0x00000] in <filename unknown>:0

I've narrowed it down to this one line of code:

WebRequest request = WebRequest.Create("http://www.google.com");

Looking through the call stack and the mono source code, I believe the failure is associated with the calling of the native 'uname' function in libc.so (the CheckOS() function, line 50 of mcs/class/System/System/Platform.cs):

if (uname (buf) == 0) {

I think what is happening is that the p/Invoke layer cannot locate libc.so. However, when I make the same call in my executable's Main() function, it executes fine, I am confused why it works in one place but not the other. It is also strange that the exception message is not a DllNotFoundException, but rather this generic "libc" message (though I have confirmed that I get the same message when I try to p/Invoke with a bogus .so).

My C code:

int main(int argc,const char* argv[]) {
    MonoDomain* domain=mono_jit_init("testFile.exe");
    MonoAssembly* assembly=mono_domain_assembly_open(domain,"testFile.exe");
    MonoImage* image=mono_assembly_get_image(assembly);

    const char* args[1];
    args[0]="testFile.exe";
    mono_jit_exec(domain,assembly,1,(char**) args);
}

My C# code:

namespace MyClass {
    class MainClass {
        public static void Main (string[] args) {
            WebRequest request=WebRequest.Create("http://www.google.com");
        }
    }
}

gcc compile options are:

gcc cTest.c -I/usr/include/mono-2.0 -DREENTRANT -lmono-2.0 -lm -lrt -ldl -lpthread

mono compile options are:

dmcs -out:testFile.exe -platform:anycpu -sdk:4.5 -target:exe -unsafe+ -main:MyClass.MainClass -reference:System,System.Configuration,System.Data,System.ServiceModel,System.Web,System.Xml *.cs

Update: I used MONO_LOG_LEVEL and MONO_LOG_MASK to trace the .so search sequence and found that the sequence on the successful call was entirely different from the unsuccessful one. So it is searching, just not very well. I then copied my libc.so.6 to the current directory, renamed to libc.so, and then set LD_LIBRARY_PATH to the same location. This gave me success. I am now having my Linux guru look into what can be done to make this solution more 'correct', but at least I have a running program. This may be the same problem as mine (though the solution's not working for me).

Upvotes: 2

Views: 1452

Answers (3)

Paul0515
Paul0515

Reputation: 25415

I've run into this issue as well. What I noticed is that the mkbundle output lists the assemblies which it embeds, and that the System.Net.dll was not included. After adding it manually on the mkbundle command line, it all worked fine.

The command line I'm using now:

mkbundle my.exe --deps --keeptemp --static --config /etc/mono/configlibc --machine-config /etc/mono/4.5/machine.config System.Net.dll -o bssetup.exe

The configlibc file is a modified copy of the default config file in that directory. The modifications were to remove all mapping lines, except the one for libc.

Hope it helps anyone!

Upvotes: 2

Daniel Le
Daniel Le

Reputation: 34

Based on your update, it looks like the application is searching for libc.so instead of libc.so.6. You got it working by manually pointing your LD_LIBRARY_PATH to the current folder having the libc.so that you copied.

Suggestion: ask your Linux guru to symlink libc.so to libc.so.6 in your normal search paths for your application to work.

Upvotes: 0

SushiHangover
SushiHangover

Reputation: 74094

The problem is you are missing the dll mapping (mono_config_parse). The following will work with mono 3.x and 4.x embedding and avoid your libc error.

#include <mono/jit/jit.h>
#include <mono/metadata/environment.h>
#include <stdlib.h>

int 
main(int argc, char* argv[]) {
    MonoDomain *domain;
    const char *file;
    int retval;

    mono_config_parse (NULL);
    domain = mono_jit_init ("textFile.exe");
    MonoAssembly *assembly;
    assembly = mono_domain_assembly_open (domain, "testFile.exe");
    mono_jit_exec (domain, assembly, argc, argv);
    retval = mono_environment_exitcode_get ();      
    mono_jit_cleanup (domain);
    return retval;
}

Certain features of the runtime like Dll remapping depend on a configuration file, to load the configuration file, just add:

mono_config_parse (NULL);

Which will load the Mono configuration file (typically /etc/mono/config).

http://www.mono-project.com/docs/advanced/embedding

FYI: On Ubuntu 15.04, I am using:

gcc main.c `pkg-config --cflags --libs mono-2`

You can update that of course to grab the mono-sgen vs. the boehm jit.

On OS-X:

gcc main.c -m32 -framework Foundation -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk \
 -lmonosgen-2.0 \
 -I/Library/Frameworks/Mono.framework/Headers/mono-2.0 \
 -L/Library/Frameworks/Mono.framework/Libraries

Upvotes: 2

Related Questions