Page 1 of 2 1 2 LastLast
Results 1 to 15 of 25

Thread: Mono 1.2.6 and Ice

  1. #1
    kovacm is offline Registered User
    Name: Michal Kovac
    Organization: Charles University in Prague
    Project: Ferda Data Mining
    Join Date
    Jan 2005
    Posts
    60

    Mono 1.2.6 and Ice

    Hi,

    I have updated Mono on my machine (running Gentoo) to version 1.2.6 and executing my application (wich is using Ice) returns this exception:
    Code:
    Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object
      at IceInternal.Network.fdToString (System.Net.Sockets.Socket socket) [0x00000]
      at IceInternal.TcpTransceiver..ctor (IceInternal.Instance instance, System.Net.Sockets.Socket fd) [0x00000]
      at IceInternal.TcpConnector.connect (Int32 timeout) [0x00000]
      at IceInternal.OutgoingConnectionFactory.create (IceInternal.EndpointI[] endpts, Boolean hasMore, Boolean threadPerConnection, System.Boolean& compress) [0x00000]
      at IceInternal.RoutableReference.createConnection (IceInternal.EndpointI[] allEndpoints, System.Boolean& comp) [0x00000]
      at IceInternal.DirectReference.getConnection (System.Boolean& comp) [0x00000]
      at Ice.ObjectDelM_.setup (IceInternal.Reference rf) [0x00000]
      at Ice.ObjectPrxHelperBase.getDelegate__ () [0x00000]
      at Ice.LocatorPrxHelper.findObjectById (Ice.Identity id, Ice.Context context__, Boolean explicitContext__) [0x00000]
      at Ice.LocatorPrxHelper.findObjectById (Ice.Identity id) [0x00000]
      at IceInternal.LocatorInfo.getEndpoints (IceInternal.IndirectReference ref, Int32 ttl, System.Boolean& cached) [0x00000]
      at Ice.ObjectAdapterI.isLocal (ObjectPrx proxy) [0x00000]
      at IceInternal.ObjectAdapterFactory.findObjectAdapter (ObjectPrx proxy) [0x00000]
      at Ice.ObjectPrxHelperBase.getDelegate__ () [0x00000]
      at Ice.ObjectPrxHelperBase.ice_isA (System.String id__, Ice.Context context__, Boolean explicitContext__) [0x00000]
      at Ice.ObjectPrxHelperBase.ice_isA (System.String id__) [0x00000]
      at IceGrid.QueryPrxHelper.checkedCast (ObjectPrx b) [0x00000]
    Did you tried mono 1.2.6? Is it bug on their side or yours? Thanks

  2. #2
    michi's Avatar
    michi is offline Registered User
    Name: Michi Henning
    Organization: Triodia Technologies
    Project: I have a passing interest in Ice :-)
    Join Date
    Feb 2003
    Location
    Brisbane, Australia
    Posts
    1,055
    We haven't tried with Mono 1.2.6 yet. I'll have a look at what's going on.

    Cheers,

    Michi.

  3. #3
    michi's Avatar
    michi is offline Registered User
    Name: Michi Henning
    Organization: Triodia Technologies
    Project: I have a passing interest in Ice :-)
    Join Date
    Feb 2003
    Location
    Brisbane, Australia
    Posts
    1,055
    The problem is that, as of Mono 1.2.6, IPEndPoint.LocalEndPoint and IPEndPoint.RemoteEndPoint return null for a socket that was connected non-blocking. (In versions prior to 1.2.6, these properties returned the correct endpoint.)

    One could argue that this is not a bug because .NET does the same thing

    If you look in Network.cs, around line 1320, you will find a number of DllImport statements. You need to replace these with the name of your C library, for example

    Code:
    #if __MonoCS__
            [DllImport("libc-2.3.6.so")]
    #else
            [DllImport("wsock32.dll")]
    #endif
            private static extern int getsockname(IntPtr s, ref sockaddr name, ref int namelen);
    Do the same for the getpeername, inet_ntoa, and ntohs imports.

    Then change the definitions of getLocalAddress and getRemoteAddress as follows:
    Code:
            public static IPEndPoint
            getLocalAddress(Socket socket)
            {
                //
                // .Net BUG: The LocalEndPoint and RemoteEndPoint properties
                // are null for a socket that was connected in non-blocking
                // mode. As of Mono 1.2.6, Mono behaves the same way.
                // The only way to make this work is to step down to
                // the native API and use platform invoke :-(
                //
                IPEndPoint localEndpoint;
                sockaddr addr = new sockaddr();
                int addrLen = 16;
    
                if(getsockname(socket.Handle, ref addr, ref addrLen) != 0)
                {
                    throw new Ice.SyscallException();
                }
                string ip = Marshal.PtrToStringAnsi(inet_ntoa(addr.sin_addr));
                int port = ntohs(addr.sin_port);
                localEndpoint = new IPEndPoint(IPAddress.Parse(ip), port);
                return localEndpoint;
            }
    
            public static IPEndPoint
            getRemoteAddress(Socket socket)
            {
                //
                // .Net BUG: The LocalEndPoint and RemoteEndPoint properties
                // are null for a socket that was connected in non-blocking
                // mode. As of Mono 1.2.6, Mono behaves the same way.
                // The only way to make this work is to step down to
                // the native API and use platform invoke :-(
                //
                IPEndPoint remoteEndpoint = null;
                sockaddr addr = new sockaddr();
                int addrLen = 16;
    
                if(getpeername(socket.Handle, ref addr, ref addrLen) == 0)
                {
                    string ip = Marshal.PtrToStringAnsi(inet_ntoa(addr.sin_addr));
                    int port = ntohs(addr.sin_port);
                    remoteEndpoint = new IPEndPoint(IPAddress.Parse(ip), port);
                }
                return remoteEndpoint;
            }
    This fixes the problem. I'm not entirely happy with this P/Invoke fix though because the library name is platform dependent

    For the moment, this fix should get you off the hook. I'll talk to the Mono people to see whether there is a better way to do this.

    Cheers,

    Michi.

  4. #4
    kovacm is offline Registered User
    Name: Michal Kovac
    Organization: Charles University in Prague
    Project: Ferda Data Mining
    Join Date
    Jan 2005
    Posts
    60

    The same icecs.dll for Windows and Linux

    thank you.

    But I don't like the fix. I would like to use the same icecs.dll on both Linux and Windows in my application.

    so I don't like this:
    #if __MonoCS__

    I found that you use it only in src\Ice\Application.cs. Can you remove it? I use Mono also on Windows so it is not the right swich and such switches should be done at runtime not at compilation time.

    You can for example define the methods twice in different classes with the same interface and at runtime check the platform...

    thanks

  5. #5
    michi's Avatar
    michi is offline Registered User
    Name: Michi Henning
    Organization: Triodia Technologies
    Project: I have a passing interest in Ice :-)
    Join Date
    Feb 2003
    Location
    Brisbane, Australia
    Posts
    1,055
    Quote Originally Posted by kovacm View Post

    But I don't like the fix. I would like to use the same icecs.dll on both Linux and Windows in my application.

    so I don't like this:
    #if __MonoCS__
    I don't like it either. But I'm afraid that there is no way to avoid this if we are forced to use P/Invoke because of a deficiency in .NET.

    I found that you use it only in src\Ice\Application.cs. Can you remove it?
    No, we use P/Invoke in a number of places, not just Application.cs.

    I use Mono also on Windows so it is not the right swich and such switches should be done at runtime not at compilation time.
    I agree that this would be preferable. But there is no mechanism in the language to delay this decision until run time. The DllImport mechanism is hopelessly broken because it requires the library name to be hardwired into the code at compile time. What really should be there is a mechanism that can accept more than one library name at run time, and search a number of libraries for a particular symbol, similar to LD_LIBRARY_PATH.

    You can for example define the methods twice in different classes with the same interface and at runtime check the platform...
    As far as I know, that's not possible for P/Invoke. But, if you have a solution to this, I'd be keen to hear about it!

    Cheers,

    Michi.

  6. #6
    rdilipk is offline Registered User
    Name: Dilip Ranganathan
    Organization: 3M
    Project: None
    Join Date
    Jul 2003
    Location
    Minnesota, USA
    Posts
    35
    I agree that this would be preferable. But there is no mechanism in the language to delay this decision until run time. The DllImport mechanism is hopelessly broken because it requires the library name to be hardwired into the code at compile time. What really should be there is a mechanism that can accept more than one library name at run time, and search a number of libraries for a particular symbol, similar to LD_LIBRARY_PATH.
    Will this help?
    CodeProject: Late binding on native DLLs with C#. Free source code and programming articles

  7. #7
    michi's Avatar
    michi is offline Registered User
    Name: Michi Henning
    Organization: Triodia Technologies
    Project: I have a passing interest in Ice :-)
    Join Date
    Feb 2003
    Location
    Brisbane, Australia
    Posts
    1,055
    Thanks for the tip. But this requires assembly language, so we'd simply swap one platform dependence for another.

    Michi.

  8. #8
    kovacm is offline Registered User
    Name: Michal Kovac
    Organization: Charles University in Prague
    Project: Ferda Data Mining
    Join Date
    Jan 2005
    Posts
    60

    DllImport loads the library at runtime

    It is true that the DllImport "requires the library name to be hardwired into the code at compile time", but the DllImport loads the library first time the method is called! So if you have in the code methods with the DllImport attribute for both linux and windows and you call only these which are in actual platform everything works.
    Last edited by kovacm; 12-18-2007 at 07:27 PM. Reason: small fix

  9. #9
    michi's Avatar
    michi is offline Registered User
    Name: Michi Henning
    Organization: Triodia Technologies
    Project: I have a passing interest in Ice :-)
    Join Date
    Feb 2003
    Location
    Brisbane, Australia
    Posts
    1,055
    Thanks for the top. The following works:

    Code:
    [DllImport("wsock32.dll", EntryPoint="getsockname")]
    private static extern int getsocknameWin(IntPtr s, ref sockaddr name, ref int namelen);
    
    [DllImport("libc.so.6", EntryPoint="getsockname")]
    private static extern int getsocknameMono(IntPtr s, ref sockaddr name, ref int namelen);
    Then the code can select which function to call at run time.

    This is a little better than #if __MonoCS__, but still has the disadvantage of hard-wiring the name of the C library.

    And, due to the limitations of the C# preprocessor, we cannot define the name of the library in the makefile and then substitute it into the code. As far as I can see, the only way to use a DllImport attribute is to have the name of the library as a string literal in the program text

    Cheers,

    Michi.

  10. #10
    kovacm is offline Registered User
    Name: Michal Kovac
    Organization: Charles University in Prague
    Project: Ferda Data Mining
    Join Date
    Jan 2005
    Posts
    60

    library

    Read Interop with Native Libraries - Mono. You can specify only a name without sufixes and prefixes, so if I uderstand correctly this is the right way for the libc.so.6:
    Code:
    [DllImport("c", EntryPoint="getsockname")]
    private static extern int getsocknameMono(IntPtr s, ref sockaddr name, ref int namelen);
    You can later override the name in mono by <dllmap/> elements in the .config file... Still not best, but better than nothing.

  11. #11
    kovacm is offline Registered User
    Name: Michal Kovac
    Organization: Charles University in Prague
    Project: Ferda Data Mining
    Join Date
    Jan 2005
    Posts
    60

    Ps

    And getsocknameGnu or getsocknameUnix (the same name as in System.PlatformID enumeration) is better name for that method, because if you are running Mono on windows this method should not be called.

  12. #12
    michi's Avatar
    michi is offline Registered User
    Name: Michi Henning
    Organization: Triodia Technologies
    Project: I have a passing interest in Ice :-)
    Join Date
    Feb 2003
    Location
    Brisbane, Australia
    Posts
    1,055
    Quote Originally Posted by kovacm View Post
    Now that looks promising. I'll have a close look at that, thanks a lot!

    Cheers,

    Michi.

  13. #13
    kovacm is offline Registered User
    Name: Michal Kovac
    Organization: Charles University in Prague
    Project: Ferda Data Mining
    Join Date
    Jan 2005
    Posts
    60
    When do you plan to release new version with the fix? (support for mono 1.2.6 + one .dll for both windows and unix)

    thanks,
    Michal

  14. #14
    matthew's Avatar
    matthew is offline ZeroC Staff
    Name: Matthew Newhook
    Organization: ZeroC, Inc.
    Project: Internet Communications Engine
    Join Date
    Feb 2003
    Location
    NL, Canada
    Posts
    1,458
    If it is possible to fix then we'll release this with Ice 3.3 due Q1 2008.

  15. #15
    kwaclaw is offline Registered User
    Name: Karl Waclawek
    Organization: Personal
    Project: Whiteboard application
    Join Date
    Sep 2004
    Location
    Oshawa, Canada
    Posts
    159
    Quote Originally Posted by michi View Post
    Now that looks promising. I'll have a close look at that, thanks a lot!

    Cheers,

    Michi.
    I saw this discussion late. Anyway, it would be on my wishlist if IceCS could be fully managed code, because than it could run in security restricted situations, where P/Invoke is not allowed.

    Regarding the issue at hand - Mono duplicating a .NET bug/deficiency, I ran your test code which I found on Google, where you demonstrated that a non-blocking socket will have null endpoint properties even if the Poll succeeded:

    Sockets and non-blocking connect - .NET C#

    I then added a simple Bind call with unspecified address and port -- s.Bind(new IPEndPoint(IPAddress.Any, 0)); -- before calling connect, and then both local and remote endpoints were not null.

    Could that work for you?

    Karl
    Karl Waclawek

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Ice & Mono - exepath and configuration
    By JensAernouts in forum Help Center
    Replies: 16
    Last Post: 03-16-2011, 03:32 PM
  2. performance about ICE on mono
    By mathgl in forum Help Center
    Replies: 1
    Last Post: 01-13-2011, 01:29 PM
  3. Mono support
    By TheRhinoDude in forum Help Center
    Replies: 4
    Last Post: 05-06-2009, 04:29 AM
  4. icecs.dll and Mono
    By kwaclaw in forum Comments
    Replies: 1
    Last Post: 11-15-2007, 07:28 PM
  5. mono c# on win32
    By panic in forum Help Center
    Replies: 5
    Last Post: 12-13-2003, 07:14 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •