Solved problem with SIGSEGV during dlopen under Mono

Nov 5, 2012 at 1:22 AM
Edited Nov 5, 2012 at 1:24 AM

Today, when I tried to run example code under Linux (GNU Debian squeeze, Mono: 2-10.8, compiled from sources), I got a SIGSEGV described as:



Stacktrace: at (wrapper managed-to-native) RDotNet.NativeLibrary.UnmanagedDll.dlopen (string,int) at RDotNet.NativeLibrary.UnmanagedDll.LoadLibrary (string) [0x0007d] in /home/mono/rnet/RDotNet.NativeLibrary/UnmanagedDll.cs:183 at RDotNet.NativeLibrary.UnmanagedDll..ctor (string) [0x00038] in /home/mono/rnet/RDotNet.NativeLibrary/UnmanagedDll.cs:39 at RDotNet.REngine..ctor (string,string) at RDotNet.REngine.CreateInstance (string,string) [0x000a3] in /home/mono/rnet/R.NET/REngine.cs:196 at TestR.NET.MainClass.Main (string[]) [0x0003b] in /home/mono/TestR.NET/TestR.NET/Main.cs:16 at (wrapper runtime-invoke) .runtime_invoke_void_object (object,intptr,intptr,intptr) Native stacktrace: /opt/mono-2.10.8/bin/mono() [0x80de8f9] /opt/mono-2.10.8/bin/mono() [0x8121edb] /opt/mono-2.10.8/bin/mono() [0x805bde1] [0xb777240c] /lib/ld-linux.so.2(+0x119a8) [0xb77849a8] /usr/lib/libdl.so(+0xc0b) [0xb6ae2c0b] /lib/ld-linux.so.2(+0xdb36) [0xb7780b36] /usr/lib/libdl.so(+0x109c) [0xb6ae309c] /usr/lib/libdl.so(dlopen+0x41) [0xb6ae2b41] [0xb6ada970] [0xb6fd3a0c] [0xb6fd3604] [0xb6fd3594] [0xb6fc85f8] [0xb6fc5e34] [0xb6fc612f] /opt/mono-2.10.8/bin/mono() [0x80639c8] /opt/mono-2.10.8/bin/mono(mono_runtime_invoke+0x40) [0x8177200] /opt/mono-2.10.8/bin/mono(mono_runtime_exec_main+0xd6) [0x817ae66] /opt/mono-2.10.8/bin/mono(mono_main+0x16d9) [0x80b9949] /opt/mono-2.10.8/bin/mono() [0x805934a] /lib/i686/cmov/libc.so.6(__libc_start_main+0xe6) [0xb75e4ca6] /opt/mono-2.10.8/bin/mono() [0x8059191] Debug info from gdb: ================================================================= Got a SIGSEGV while executing native code. This usually indicates a fatal error in the mono runtime or one of the native libraries used by your application. ================================================================= bash: line 1: 16397 Przerwane /opt/mono-2.10.8/bin/mono --debug "/home/mono/TestR.NET/TestR.NET/bin/Debug/TestR.NET.exe"

I've found that this is not a problem with the libR.so or libdl.so but rather with the Mono itself. This is already reported as a bug on the Xamaring bugzilla.

Fortunately I've found a working solution. In short, you have to write in C a simple wrapper for the libdl.so and call its functions instead of calling directly libdl.so. This works perfectly, but me and the author of the solution don't know why.

The solution is described HERE.

Things to do:

1. Create a C file (libfakedl.c) with this content:


#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

void* dlopen(const char* file, int flag) {
    void* ret;
    ret = dlopen(file,flag);
    return ret;
}

char* dlerror() {
    char* err;
    err = dlerror();
    return err;
}

void* dlsym(void* handle, const char* symbol) {
    void* ret;
    ret = dlsym(handle,symbol); 
    return ret;
}

int dlclose(void* handle) {
    return dlclose(handle);
}

 

2. Compile it:

gcc -Wall -fPIC -c libfakedl.c
gcc -shared -o libfakedl.so libfakedl.o
su
cp libfakedl.so /lib

 

3. Edit file RDotNet.NativeLibrary -> UnmanagedDll.cs and replace

[DllImport("libdl.so")]

with

[DllImport("libfakedl.so")]

 

4. Recompile all

5. Remember to set both PATH and R_HOME variables!

6. Under Mono on Linux you may have to define the UNIX preprocessor variable (I had to do this).

#define UNIX

7. You're done :)

Screenshot: http://s18.postimage.org/wm4tiaabt/rnet_working.png