zeromq / clrzmq4

ZeroMQ C# namespace (.NET and mono, Windows, Linux and MacOSX, x86 and amd64)
GNU Lesser General Public License v3.0
237 stars 112 forks source link

Crash in ZSocket.SendMessage() #200

Open chrbauer opened 4 years ago

chrbauer commented 4 years ago

There is a problem in the SendMessage(ZMessage) implementation. SendMessage(ZMessage) will call SendFrames(msg as IEnumerable) (ZSocket.cs at line 667). Here is the problem.

                public virtual bool SendFrames(IEnumerable<ZFrame> frames, ref int sent, ZSocketFlags flags, out ZError error)
        {
            // ... 
            bool framesIsList = frames is IList<ZFrame>;  // true for ZMessage
            ZFrame[] _frames = frames.ToArray();

            for (int i = 0, l = _frames.Length; i < l; ++i)
            {
                ZFrame frame = _frames[i];

                if (i == l - 1 && !more)
                {
                    flags = flags & ~ZSocketFlags.More;
                }

                if (!SendFrame(frame, flags, out error)) // now you are not allowed to call frame.Dispose() anymore
                {
                    return false;
                }

                if (framesIsList)
                {
                    ((IList<ZFrame>)frames).Remove(frame); // calls ZMessage.Remove(frame, true), which disposes the frame. See ZMessage.cs:321 and 334
                }

                ++sent;
            }

            return true;
        }

I get a NullReferenceException with this call stack. I thinks it's related

15:00:44    bei ZeroMQ.ZMessage.Remove(ZFrame item)
15:00:44    bei ZeroMQ.ZSocket.SendFrames(IEnumerable`1 frames, Int32& sent, ZSocketFlags flags, ZError& error)
15:00:44    bei ZeroMQ.ZSocket.SendFrames(IEnumerable`1 frames, ZSocketFlags flags, ZError& error)
15:00:44    bei ZeroMQ.ZSocket.SendMessage(ZMessage msg, ZSocketFlags flags, ZError& error)
15:00:44    bei ZeroMQ.ZSocket.SendMessage(ZMessage msg, ZSocketFlags flags)
15:00:44    bei ZeroMQ.ZSocket.SendMessage(ZMessage msg)