Bug 4190 - SIGSEGV when P/Invoke dlopen
Summary: SIGSEGV when P/Invoke dlopen
Status: RESOLVED INVALID
Alias: None
Product: Runtime
Classification: Mono
Component: Interop ()
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-04-02 13:33 UTC by Luca Piccioni
Modified: 2012-09-02 13:28 UTC (History)
5 users (show)

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


Attachments
The test source file. (413 bytes, text/x-csharp)
2012-04-02 13:33 UTC, Luca Piccioni
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED INVALID

Description Luca Piccioni 2012-04-02 13:33:13 UTC
Created attachment 1611 [details]
The test source file.

// Main.c
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char *argv[])
{
        void *libraryHandle = dlopen("libc.so.6", 2);
        printf("Success! %x\n", libraryHandle);
}
//EOF

luca@monster:~/Projects/DlopenTest/DlopenTest$ gcc Main.c -ldl
luca@monster:~/Projects/DlopenTest/DlopenTest$ ./a.out 
Success! b7828b10

"Indeed it works. I'm trying to to that in C#. I'm trying to port a code section to be portable also on Linux. In windows I use LoadLibrary and others."

"I'm running on Debian 6.0.4" (Stable). I've also tested with mono 2.10-2, built with "./configure --prefix=/opt/mono-2.10 && make && make install"; the test was run with "/opt/mono-2.10/bin/mono ./Main.exe". I've also tried different marshalling methods for 'dlopen' first argument, but with no luck (I think that LPStr should be good)".

I've also straced the application. You can find the log here (http://stackoverflow.com/questions/9954548/sigsegv-when-p-invoking-dlopen).

// Main.cs
using System;
using System.Runtime.InteropServices;

namespace DlopenTest
{
        class MainClass
        {
                const int RTLD_NOW = 2;

                [DllImport("dl")]
                static  extern IntPtr dlopen(string filename, int flags);

                public static void Main (string[] args)
                {
                        string library = "libc.so.6";
                        IntPtr libraryHandle = dlopen(library, RTLD_NOW);
                        Console.WriteLine ("Success! {0}", libraryHandle.ToString());
                }
        }
}
// EOF


luca@monster:~/Projects/DlopenTest/DlopenTest$ mono --version
Mono JIT compiler version 2.6.7 (Debian 2.6.7-5)
Copyright (C) 2002-2010 Novell, Inc and Contributors. www.mono-project.com
	TLS:           __thread
	GC:            Included Boehm (with typed GC and Parallel Mark)
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  x86
	Disabled:      none
luca@monster:~/Projects/DlopenTest/DlopenTest$ mcs Main.cs 
luca@monster:~/Projects/DlopenTest/DlopenTest$ ./Main.exe 
Stacktrace:

  at (wrapper managed-to-native) DlopenTest.MainClass.dlopen (string,int) <0x00004>
  at (wrapper managed-to-native) DlopenTest.MainClass.dlopen (string,int) <0x00004>
  at DlopenTest.MainClass.Main (string[]) <0x0001b>
  at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <0x00043>

Native stacktrace:

	/usr/bin/cli() [0x80d5b19]
	/usr/bin/cli() [0x810f7ab]
	[0xb770f40c]
	/lib/ld-linux.so.2(+0x119a8) [0xb77219a8]
	/usr/lib/libdl.so(+0xc0b) [0xb53ddc0b]
	/lib/ld-linux.so.2(+0xdb36) [0xb771db36]
Comment 1 Florian Kummer 2012-08-20 06:29:46 UTC
I have the same problem; what I figured out:

* it seems to affect only the x86 architecture
* it seems to be present in almost any mono version; I especially tested:
  - mono 2.6.7 (Debian 2.6.7-5.1) on Debian 6.0 
  - mono 2.11.2 (tarball)
  - mono 2.8.something on OpenSUSE

On the x64 Systems, i never had a problem like that;
Comment 2 Florian Kummer 2012-08-22 16:06:03 UTC
I just did some further investigation of the problem; Using 'gdb' on mono gives me the following information:

Please have a close look on #1 (highligted with *****). The 'mode'-parameter,
where I passed the value 2 is actually -2147483646.
Beside that, the 'file'-parameter seems to arrive correctly. (I'm just using libmpi_f77.so instead of the libc.so.6, which Luca is using above.)


#0  _dl_debug_initialize (ldbase=0, ns=-2) at dl-debug.c:60                                                                                                
****************************************************************************
#1  0xb7ff49a8 in _dl_open (file=0x83b29c8 "libmpi_f77.so", mode=-2147483646, caller_dlopen=0xb790be48, nsid=-2, argc=2, argv=0xbffff504, env=0xbffff510)
    at dl-open.c:582                                                                                                                                       
****************************************************************************
#2  0xb7787c0b in ?? () from /usr/lib/libdl.so                                                                                                             
#3  0xb7ff0b36 in _dl_catch_error (objname=<value optimized out>, errstring=<value optimized out>, mallocedp=<value optimized out>, operate=0xb7787b70, 
    args=0xbffff1c0) at dl-error.c:178                                                                                                                     
#4  0xb778809c in ?? () from /usr/lib/libdl.so
#5  0xb7787b41 in dlopen () from /usr/lib/libdl.so                                                                                                         
#6  0xb790be48 in ?? ()                                                                                                                                    
#7  0xb790bcf8 in ?? ()
#8  0xb790bdcf in ?? ()
#9  0x08063908 in mono_jit_runtime_invoke (method="MPI.Wrappers.Utils.DynamicLibraries:Main ()", obj=0x0, params=0xbffff31c, exc=0x0) at mini.c:5791
#10 0x081a3df0 in mono_runtime_invoke (method="MPI.Wrappers.Utils.DynamicLibraries:Main ()", obj=0x0, params=0xbffff31c, exc=0x0) at object.c:2755
#11 0x081a7a56 in mono_runtime_exec_main (method="MPI.Wrappers.Utils.DynamicLibraries:Main ()", args=0x3be00, exc=0x0) at object.c:3938
#12 0x080b9985 in main_thread_handler (argc=2, argv=0xbffff504) at driver.c:1003
#13 mono_main (argc=2, argv=0xbffff504) at driver.c:1855
#14 0x080592aa in mono_main_with_options (argc=2, argv=0xbffff504) at main.c:66
#15 main (argc=2, argv=0xbffff504) at main.c:97
Comment 3 Zoltan Varga 2012-08-26 08:58:28 UTC
These problems are usually caused by the loaded library itself, i.e. loading a 64 bit library into a 32 bit process or vice versa, loading multiple versions of the same library etc.
Comment 4 Florian Kummer 2012-08-28 05:22:22 UTC
I've found a - quite strange - solution:
I compiled my own library which just wraps libdl.so - all problems removed.
It works for me, but I have no explanation.
(see below)


-------------------------------------------------------------------------
(1) libfakedl.c
-------------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

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

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

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

int my_dlclose(void* handle) {
    return dlclose(handle);
}
-----------------------------------------------------------------------
(2) compile and "install"
-----------------------------------------------------------------------
$ gcc -Wall -fPIC -c libfakedl.c
$ gcc -shared -o libfakedl.so libfakedl.o
$ sudo cp libfakedl.so /lib
-----------------------------------------------------------------------
(3) ~/.mono/config
-----------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <dllmap dll="fakedl-1" target="/lib/libfakedl-2.so"/>
    <dllmap dll="dl">
      <dllentry dll="/lib/libfakedl.so" name="dlopen"  target="my_dlopen"  />
      <dllentry dll="/lib/libfakedl.so" name="dlclose" target="my_dlclose" />
      <dllentry dll="/lib/libfakedl.so" name="dlsym"   target="my_dlsym"   />
      <dllentry dll="/lib/libfakedl.so" name="dlerror" target="my_dlerror" />
    </dllmap>
</configuration>