[xsd-users] Bug in ACE CDR deserialization

James Frullo jamesfrullo at gmail.com
Wed Jul 25 10:39:20 EDT 2007


Hi Boris.  Actually, the function ACE::strdelete() does exist; it's not
something I just made up.  In C++ Network Programming, Volume 2, Schmidt
explains the need for it.  You can find that explanation here:
http://www.mamiyami.com/document/cpp_network_prog_volume2/0201795256_ch05lev1sec2.html
Look for "Sidebar 29: Portable Heap Operations with ACE".

Calling ACE::strdelete() in line like that is certainly ugly.  That's why I
suggested adding a special auto ptr class for ACE strings, like this:

template<typename X>
struct auto_ACE_str
{
auto_ACE_str(X a[]) : a_(a) {}
~auto_ACE_str() {ACE::strdelete(a_);}
private:
X *a_;
};

This still isn't as elegant as the current implementation, but it has the
advantage of working portably.

By the way, this is a great feature to be able to do binary serialization.
This makes the tool much more useful.

~James

On 7/25/07, Boris Kolpackov <boris at codesynthesis.com> wrote:
>
> Hi James,
>
> James Frullo <jamesfrullo at gmail.com> writes:
>
> > I built ACE by linking to the Multi-threaded Debug DLL version
> > of the CRT, but I built the sample using the plain Multi-threaded Debug
> > version.  This brought out a non-obvious bug in the implementation of
> the
> > following function:
> > inline istream<ACE_InputCDR>& operator>> (istream<ACE_InputCDR>& s,
> > std::basic_string<char>& x)
>
> This is really a bug in the Windows DLL model, not in the above
> function. I don't think it will be fixed any type soon, though ;-).
>
>
> > The problem with this is that calling read_string() gives you memory
> > allocated by ACE.  But auto_array is going to deallocate that memory by
> > calling delete[].  Since ACE is compiled and linked separately, it is
> > incorrect to assume that this will work.  In fact, it does not work.  It
> > crashes because using the build configurations I mentioned above.  The
> > correct code would be something like:
> >
> >        ACE_CDR::Char* r;
> >
> >        if (!s.impl ().read_string (r))
> >          throw ace_cdr_stream_extraction ();
> >
> >        try {x = r} catch(...){ACE::strdelete(r);throw;}
> >        ACE::strdelete(r);
> >
> >        return s;
> >
> > Of course, this is ugly. A nicer way would be to have an ace_auto_str()
> > class (or whatever).
>
> It is not just ugly, it simply won't work because there is no strdelete
> or anything similar that I am aware of. ACE CDR code uses new[] to
> allocate the memory and delete[] to free it. There is no wrapper to
> call "ACE's version of delete[]". The only way to make it work (aside
> from linking your application with the DLL version of the runtime) is
> to handle string serialization ourselves which would require copying
> quite a bit of implementation details from ACE to the above function.
> This is a bad idea in itself because that code can change in the future.
> Furthermore, the code that handles wchar_t serialization (that would
> need to be copied as well) is really messy and has various branches
> for different versions of GIOP. I really don't think it is a good idea
> to drag it into XSD.
>
> I will think some more about other possible ways to fix this. If you
> have any ideas, let me know. And thanks for reporting this!
>
>
> -boris
>



More information about the xsd-users mailing list