Go Back   ZeroC Forums > Bug Reports

Reply
 
LinkBack Thread Tools Rate Thread Display Modes
  #1 (permalink)  
Old 12-17-2007
kovacm 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
Reply With Quote
  #2 (permalink)  
Old 12-17-2007
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 889
We haven't tried with Mono 1.2.6 yet. I'll have a look at what's going on.

Cheers,

Michi.
Reply With Quote
  #3 (permalink)  
Old 12-18-2007
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 889
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.
Reply With Quote
  #4 (permalink)  
Old 12-18-2007
kovacm 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
Reply With Quote
  #5 (permalink)  
Old 12-18-2007
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 889
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.

Quote:
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.

Quote:
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.

Quote:
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.
Reply With Quote
  #6 (permalink)  
Old 12-18-2007
rdilipk rdilipk is offline
Registered User
 
Name: Dilip Ranganathan
Organization: 3M
Project: None
 
Join Date: Jul 2003
Location: Minnesota, USA
Posts: 35
Quote:
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
Reply With Quote
  #7 (permalink)  
Old 12-18-2007
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 889
Thanks for the tip. But this requires assembly language, so we'd simply swap one platform dependence for another.

Michi.
Reply With Quote
  #8 (permalink)  
Old 12-18-2007
kovacm 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
Reply With Quote
  #9 (permalink)  
Old 12-18-2007
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 889
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.
Reply With Quote
  #10 (permalink)  
Old 12-19-2007
kovacm 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.
Reply With Quote
  #11 (permalink)  
Old 12-19-2007
kovacm 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.
Reply With Quote
  #12 (permalink)  
Old 12-19-2007
michi's Avatar
michi michi is offline
ZeroC Staff
 
Name: Michi Henning
Organization: ZeroC
Project: Ice
 
Join Date: Feb 2003
Location: Brisbane, Australia
Posts: 889
Quote:
Originally Posted by kovacm View Post
Now that looks promising. I'll have a close look at that, thanks a lot!

Cheers,

Michi.
Reply With Quote
  #13 (permalink)  
Old 12-20-2007
kovacm 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
Reply With Quote
  #14 (permalink)  
Old 12-20-2007
matthew's Avatar
matthew matthew is offline
ZeroC Staff
 
Name: Matthew Newhook
Organization: ZeroC, Inc.
Project: Internet Communications Engine
 
Join Date: Feb 2003
Location: NL, Canada
Posts: 1,001
If it is possible to fix then we'll release this with Ice 3.3 due Q1 2008.
Reply With Quote
  #15 (permalink)  
Old 12-23-2007
kwaclaw kwaclaw is offline
Registered User
 
Name: Karl Waclawek
Organization: Toronto Star Newspapers Ltd.
Project: Proof of concept
 
Join Date: Sep 2004
Location: Oshawa, Canada
Posts: 123
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
The Toronto Star - http://www.thestar.com
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads
Thread Thread Starter Forum Replies Last Post
icecs.dll and Mono kwaclaw Comments 1 11-15-2007 07:28 PM
Mono and IceSSL Status tkrieger Help Center 6 11-10-2006 08:29 AM
IcePack + Debian Linux + Mono + NoEndpointException kovacm Bug Reports 10 07-20-2005 06:29 AM
Problems compiling IceCS with mono on Fedora Core 3 iostream Help Center 5 12-10-2004 05:52 PM
mono c# on win32 panic Help Center 5 12-13-2003 07:14 PM


All times are GMT -4. The time now is 10:39 AM.


Powere