SIGSEGV при P / Invoking dlopen - PullRequest
       6

SIGSEGV при P / Invoking dlopen

3 голосов
/ 31 марта 2012

Я пытаюсь написать абстракцию для загрузки динамических библиотек в Windows и Linux. Хотя на платформе Windows все идет хорошо, я получаю SIGSEGV при звонке 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!");
        }
    }
}

Вывод следующий:

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

Что происходит?

Моя версия glibc - 2.11.3, а монофоническая среда выполнения - 2.6.3.

Для компиляции программы: mono-csc Main.cs Для запуска программы: ./Main.exe


Я только что выполнил тестовое приложение. Вот системные вызовы перед 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) ---

Этот след генерируется путем вызова "strace /opt/mono-2.10/bin/mono ./DlopenTest.exe 2> strace"

Направление моно установки по умолчанию (2.6) почти одинаково, и он всегда падает в одной и той же точке.

Как отладить это условие? У меня нет идей ... Может быть dlopen - это просто оболочка, поэтому я могу вызвать альтернативную функцию? Может быть, я выполняю моно 2.10 в неправильном окружении (возможно, мне нужно указать некоторую переменную окружения, чтобы получить эту работу)?

Ответы [ 2 ]

3 голосов
/ 31 марта 2012

Ваш код работает на 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!

Кажется, что он вышел из строя под 2.6 (что-то довольно распространенное), но этой версии много лет ... Я настоятельно рекомендую вам обновить.

2 голосов
/ 05 ноября 2012

Это хорошо известная ошибка во многих различных версиях Mono.Вот рабочее решение: https://bugzilla.xamarin.com/show_bug.cgi?id=4190

Вкратце: создайте простую оболочку на C / C ++ для libdl.so (libfakedl.so) и косвенно вызывайте ее функции через оболочку.

Решено: http://s15.postimage.org/8x95bygh7/libdl_solved.png

...