Hide Forgot
Description of problem: See https://issues.apache.org/jira/browse/QPID-3193 The .NET Binding does not deal well with copied .NET binding objects. (1) Message mA = new Message("a"); (2) Message mB = mA; ... (N) mB.Dispose(); After disposing of message mB then message mA is clobbered. 'Message' is a 'ref class' type and messages mA and mB refer to the same object on managed heap. When message mB is disposed then the bound C++ Messaging object is deleted. Any reference to the bound message part of mA will result in an illegal memory reference (to 0). All references to bound message objects need: 1. A lock to prevent aliased copies from deleting the bound C++ objects. 2. A NULL test with a throw to prevent accessing deleted bound C++ objects. Version-Release number of selected component (if applicable): 2.0.0.1 How reproducible: 100% Steps to Reproduce: 1. See description above. Actual results: Exception System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at qpid.messaging.Message.getContentSize(Message* ) at Org.Apache.Qpid.Messaging.Message.get_ContentSize() in d:\qpid\cpp\bindings\qpid\dotnet\src\message.h:line 350 at Org.Apache.Qpid.Messaging.Program.Main(String[] args) in D:\qpid\cpp\...\csharp.example.helloworld.cs:line 80. Expected results: A formal ObjectDisposedException. Additional info: This could be fixed with the addition of: msclr::lock lk(lockObject); if (NULL == messagep) throw gcnew ObjecteDisposedException("Message"); to each bound function and property accessor.
This problem is fixed upstream at checkin r1221824. The following test program: class Program { static void Main(string[] args) { Message msgA = new Message("abc"); Message msgB = msgA; // Now msgA and msgB are .NET references to the same .NET Message. // Disposing of either of them disposes of the other. msgB.Dispose(); // Check that Message msgA is still safe Console.WriteLine("Message msgA IsDisposed : {0}", msgA.IsDisposed); // msgA is disposed. Reference it anyway and get the exception. try { Console.WriteLine("Message msgA content = {0}", msgA.GetContent()); } catch (Exception e) { Console.WriteLine("Exception {0}.", e); } } } Produces the following output: Message msgA IsDisposed : True Exception System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Org.Apache.Qpid.Messaging.Message'. at Org.Apache.Qpid.Messaging.Message.ThrowIfDisposed() in d:\qpid\cpp\bindings\qpid\dotnet\src\message.cpp:line 54 at Org.Apache.Qpid.Messaging.Message.GetContent() in d:\qpid\cpp\bindings\qpid\dotnet\src\message.cpp:line 413 at Org.Apache.Qpid.Messaging.Program.Main(String[] args) in D:\qpid\cpp\bindings\qpid\dotnet\examples\example\example.cs:line 127. Clearly the ObjectDisposedException provides useful information for a user who expects his exception handler to actually work.
Created attachment 549357 [details] Setup instructions and code to test this bz using Managed C++ Microsoft .NET Managed C++ behaves differently from other .NET languages. I set up a C++ project to characterize and to test this bug and in the process had several difficulties getting started. This attachment may help testers who want to get started using C++ instead of C#.
This bug has been fixed for a while (since 0.16).
The bug was reproduced on qpid-cpp-win-3.0.0.5-1; on qpid-cpp-win-3.2.0.4-1 did not occur.
References to deleted objects are detected and correct type of exception (System.ObjectDisposedException) is raised. Verified on packages qpid-cpp-win-3.22.5.1-1 on all supported Windows platforms: WindowsXP-x86, Windows7-x86 and x64, Windows Server2003-x86 and x64, Windows Server2008-x86, x64 and R2. --> VERIFIED
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. http://rhn.redhat.com/errata/RHEA-2014-1296.html