[Insight-developers] ExceptionObject assignment crash on MSVC

Niels Dekker niels-xtk at xs4all.nl
Fri May 30 20:26:26 EDT 2008


Thanks for your research on this, Luis. I'm sorry it all takes much more 
time than expected. When I submitted the bug report, I thought the 
attached patch would fix it instantly...

You wrote:
> In Visual Studio 7.1, the superclass of itk::ExceptionObject,
> the std::exception, is not initializing its "what" component.
>
> When running in Debug mode, it crashes in the expressions
>     std::cout <<  E << std::endl;
> the "what" component of std::exception is only set at construction
> time, and we are not explicitly setting it up.

It could well be that there's a problem with the "what" component of 
MSVC's std::exception.  But if so, it would be a bug of their 
implementation.  Because according to the C++ Standard, std::exception 
doesn't have a "what" component.  It only has a "what()" function.  The 
overloaded exception(const char *) constructor is a Microsoft specific 
extension to the C++ Library.  So please do not commit the changes you 
just suggested (below here), because they won't work on other platforms.

See also: "std::exception's constructors according to C++ standard" 
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=200471

So I still think that the crash is caused by a bug in MSVC's 
std::exception::operator=.  When debugging, it looks like it's messing 
up the virtual table of itk::ExceptionObject.

Anyway, I also made a quite horrible bug myself:

  const char *
  ExceptionObject::what() const throw()
  {
    // Note: m_What.c_str() wouldn't be...
    return this->GetExceptionData()->m_WhatPointer;
  }

Oops, I forgot to check whether the data was NULL!  Which is the case 
when ExceptionObject is default-constructed.  So it should be something 
like this:

  const char *
  ExceptionObject::what() const throw()
  {
   const ExceptionData * const thisData = this->GetExceptionData();

    // Note: m_What.c_str() wouldn't be...
   return thisData ? thisData->m_WhatPointer : "";
  }

But I'm too sleepy to fix it now...  Feel free to fix 
ExceptionObject::what(), if you have the time.  Otherwise I'll try to do 
so tomorrow.

Good night,

Niels

> -------------------------------------------------------------
> $ cvs -q diff
> Index: itkExceptionObject.cxx
> ===================================================================
> RCS file:
> /cvsroot/Insight/Insight/Code/Common/itkExceptionObject.cxx,v
> retrieving revision 1.14 diff -r1.14 itkExceptionObject.cxx
> 134c134
> < ExceptionObject::ExceptionObject()
> ---
>> ExceptionObject::ExceptionObject():Superclass("")
> 144c144
> < :
> ---
>>> Superclass(desc),
> 154c154
> < :
> ---
>>> Superclass(desc.c_str()),
> 161c161
> < Superclass(orig),
> ---
>> Superclass(orig.what()),
>> ------------------------------------------------------ 
>
> This bring us up to the next problem:
>
>
> Apparently in the triple assignment:
>
>         E = F = G;
>
> Something goes wrong in the reference counting of E,F,G
> is done improperly, and when we get to the next line:
>
>          std::cout << F << std::endl;
>
> it attempts to use an invalid object for invoking
> its Print() method.
>
>
>      This requires a closer look....
>
>
> ...and still is unclear why is that it is a
> problem only in VS71 (and maybe the same in VS6 ?).
>
>
>
>     Luis



More information about the Insight-developers mailing list