Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SIGSEGV when P/Invoking dlopen

I'm trying to write an abstraction to load dynamic libraries on Windows and Linux. While on Windows platform everything goes fine, I get a SIGSEGV when I call dlopen:

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

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

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

        [DllImport("dl")]
        static extern IntPtr dlsym(IntPtr handle, [MarshalAs(UnmanagedType.LPTStr)] string symbol);

        public static void Main (string[] args)
        {
            IntPtr libraryHandle = dlopen("libc.so.6", RTLD_NOW);

            Console.WriteLine ("Success!");
        }
    }
}

The output is the following:

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[]) [0x00000] in     /home/luca/Projects/DlopenTest/DlopenTest/Main.cs:18
  at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object     (object,intptr,intptr,intptr) <IL 0x0001d, 0x00043>

Native stacktrace:

    /usr/bin/mono() [0x80d5b19]
    /usr/bin/mono() [0x810f7ab]
    [0xb771940c]
    /lib/ld-linux.so.2(+0x119a8) [0xb772b9a8]
/usr/lib/libdl.so(+0xc0b) [0xb536dc0b]
/lib/ld-linux.so.2(+0xdb36) [0xb7727b36]
/usr/lib/libdl.so(+0x109c) [0xb536e09c]
/usr/lib/libdl.so(dlopen+0x41) [0xb536db41]
[0xb58672f1]
[0xb58671bd]
[0xb5867234]
/usr/bin/mono() [0x8064428]
/usr/bin/mono(mono_runtime_invoke+0x40) [0x812d4e0]
/usr/bin/mono(mono_runtime_exec_main+0xde) [0x8130f8e]
/usr/bin/mono(mono_runtime_run_main+0x112) [0x8131292]
/usr/bin/mono(mono_main+0x15ec) [0x80b3bdc]
/usr/bin/mono() [0x805b675]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe6) [0xb74b8ca6]
/usr/bin/mono() [0x805b5b1]

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.
=================================================================

What's going on?

My glibc version is 2.11.3, and the mono runtime is 2.6.3.

To compile the program: mono-csc Main.cs To run the program: ./Main.exe


I've just straced the execution of the test application. Here is the system calls before the SIGSGV:

...
open("/usr/lib/libdl.so", O_RDONLY)     = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0@\n\0\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0644, st_size=9736, ...}) = 0
mmap2(NULL, 12408, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb598b000
mmap2(0xb598d000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3,     0x1) = 0xb598d000
close(3)                                = 0
mprotect(0xb598d000, 4096, PROT_READ)   = 0
munmap(0xb598f000, 76774)               = 0
gettimeofday({1333269422, 515602}, NULL) = 0
gettimeofday({1333269422, 515653}, NULL) = 0
gettimeofday({1333269422, 515828}, NULL) = 0
gettimeofday({1333269422, 515884}, NULL) = 0
gettimeofday({1333269422, 515986}, NULL) = 0
gettimeofday({1333269422, 516059}, NULL) = 0
gettimeofday({1333269422, 516613}, NULL) = 0
gettimeofday({1333269422, 516670}, NULL) = 0
brk(0x98e3000)                          = 0x98e3000
brk(0x98e1000)                          = 0x98e1000
gettimeofday({1333269422, 516916}, NULL) = 0
brk(0x98de000)                          = 0x98de000
brk(0x98dc000)                          = 0x98dc000
brk(0x98db000)                          = 0x98db000
gettimeofday({1333269422, 517092}, NULL) = 0
gettimeofday({1333269422, 517200}, NULL) = 0
gettimeofday({1333269422, 517261}, NULL) = 0
gettimeofday({1333269422, 517368}, NULL) = 0
gettimeofday({1333269422, 517525}, NULL) = 0
gettimeofday({1333269422, 517762}, NULL) = 0
gettimeofday({1333269422, 517823}, NULL) = 0
gettimeofday({1333269422, 518007}, NULL) = 0
gettimeofday({1333269422, 518074}, NULL) = 0
gettimeofday({1333269422, 518435}, NULL) = 0
gettimeofday({1333269422, 518486}, NULL) = 0
gettimeofday({1333269422, 518648}, NULL) = 0
gettimeofday({1333269422, 518699}, NULL) = 0
gettimeofday({1333269422, 518803}, NULL) = 0
futex(0xb598e06c, FUTEX_WAKE_PRIVATE, 2147483647) = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---

This trace is generated by invoking "strace /opt/mono-2.10/bin/mono ./DlopenTest.exe 2> strace"

The strace of default mono installation (2.6) it almost similar, and it always crashing at the same point.

How to debug this condition? I'm out of ideas... Maybe dlopen is just a wrapper, so I can call an alternative function? Maybe I execute mono 2.10 in a wrong environement (maybe I have to specify some environment variable to get this work)?

like image 656
Luca Avatar asked Dec 29 '25 01:12

Luca


2 Answers

Your code works on Mono 2.10.

$ mono --version
Mono JIT compiler version 2.10.5 (Debian 2.10.5-1)
Copyright (C) 2002-2011 Novell, Inc, Xamarin, Inc and Contributors. www.mono-project.com
    TLS:           __thread
    SIGSEGV:       altstack
    Notifications: epoll
    Architecture:  x86
    Disabled:      none
    Misc:          softdebug 
    LLVM:          supported, not enabled.
    GC:            Included Boehm (with typed GC and Parallel Mark)
$ cat so.cs
using System;
using System.Runtime.InteropServices;

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

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

        [DllImport("dl")]
        static extern IntPtr dlsym(IntPtr handle, [MarshalAs(UnmanagedType.LPTStr)] string symbol);

        public static void Main (string[] args)
        {
            IntPtr libraryHandle = dlopen("libc.so.6", RTLD_NOW);

            Console.WriteLine ("Success!");
        }
    }
}
$ mcs so.cs
so.cs(18,20): warning CS0219: The variable `libraryHandle' is assigned but its value is never used
Compilation succeeded - 1 warning(s)
$ mono so.exe
Success!

It seems it failed under 2.6 (it's something pretty common) but that version if many years old... I strongly suggest you upgrade.

like image 109
poupou Avatar answered Dec 31 '25 17:12

poupou


This is a well known bug in many different versions of Mono. Here is a working solution: https://bugzilla.xamarin.com/show_bug.cgi?id=4190

In short: create a simple wrapper in C/C++ for libdl.so ( libfakedl.so) and call its functions indirectly through the wrapper.

Solved: http://s15.postimage.org/8x95bygh7/libdl_solved.png

like image 37
devstat Avatar answered Dec 31 '25 16:12

devstat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!