C# 调用dlopen时的SIGSEGV

C# 调用dlopen时的SIGSEGV,c#,.net,linux,mono,dlopen,C#,.net,Linux,Mono,Dlopen,我正试图编写一个抽象来加载Windows和Linux上的动态库。虽然在Windows平台上一切正常,但当我调用dlopen: // File: Main.cs using System; using System.Runtime.InteropServices; namespace DlopenTest { class MainClass { const int RTLD_NOW = 2; [DllImport("dl")]

我正试图编写一个抽象来加载Windows和Linux上的动态库。虽然在Windows平台上一切正常,但当我调用
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.
=================================================================
此跟踪是通过调用“
strace/opt/mono-2.10/bin/mono./DlopenTest.exe 2>strace
”生成的

默认mono安装(2.6)的策略几乎相似,并且总是在同一点崩溃


如何调试这种情况?我没有主意了。。。也许dlopen只是一个包装器,所以我可以调用另一个函数?也许我在一个错误的环境中执行mono 2.10(也许我必须指定一些环境变量才能完成这项工作)

您的代码在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下失败了(这是很常见的事情),但是这个版本如果有很多年了。。。我强烈建议您升级。

这是许多不同版本Mono中众所周知的错误。以下是一个可行的解决方案:

简而言之:在C/C++中为libdl.so(libfakedl.so)创建一个简单的包装器,并通过包装器间接调用其函数


已解决:

如果您提供了完整的测试用例和关于如何构建它的说明,我会帮助您调试它。提示:了解dlopen内部结构的人很少也知道如何编写
C
code。更新了问题。阅读关于dlopen的代码似乎是合理的,关于参数编组,我尝试了几乎所有的组合。发布错误报告,您的代码适合我。使用
Mono JIT编译器版本2.4.4(Debian 2.4.4~svn151842-1ubuntu4)也适合我。
非常常见的(同时,从源代码生成Mono)。升级,但没有运气:它还是崩溃了。问题出在glibc上吗?我不太愿意使用这个选项……在对我的系统进行全面升级后,我的测试用例运行良好。我已经发布了一个bug报告。自从bug被我打开后我就知道了。
$ 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!