Crash in WatershedImageFilter

Hi,
I am trying to run WatershedImageFilter class function with this arguments(image -{0.,0.,0.,0.,1.f/4503599627370496.f,0.,0.}, 1.0(Level), 0.0(Threshold)).

#include "itkWatershedImageFilter.h"
#include "itkCastImageFilter.h"
#include "itkRelabelComponentImageFilter.h"
#include <vector>
#include <math.h>

int main( int argc, char *argv[] ) {
  typedef float InternalPixelType;

  const unsigned int Dimension = 2;

  typedef  itk::Image< float, Dimension > InputImageType;
  typedef  itk::Image< double, Dimension > OutputImageType;

  InputImageType::Pointer image = InputImageType::New();

  int width = 7;
  int height = 1;
  InputImageType::SizeType  size;
  size[0] = width;
  size[1] = height;

  InputImageType::RegionType region;
  region.SetSize( size );

  image->SetRegions( region );
  image->Allocate();
  constexpr float gyot = (1.f/4503599627370496.f);
  std::vector<float> arr = {0.,0.,0.,0.,gyot,0.,0.};
  memcpy(image->GetBufferPointer(), arr.data(), width * height * sizeof(float));


  typedef itk::WatershedImageFilter<InputImageType> WatershedFilterType;
  typedef  itk::Image<itk::IdentifierType, Dimension> FilteredImageType;
  typedef   itk::CastImageFilter<FilteredImageType, OutputImageType> CastFilterType; 
  typedef  itk::RelabelComponentImageFilter<FilteredImageType, FilteredImageType> RelabelFilterType;

  WatershedFilterType::Pointer watershedFilter = WatershedFilterType::New();

  watershedFilter->SetInput( image );
  watershedFilter->SetLevel( 1.0 );
  watershedFilter->SetThreshold( 0.0 );
  
  typename RelabelFilterType::Pointer relabeler = RelabelFilterType::New();
  relabeler->SetInput(watershedFilter->GetOutput());

  typename CastFilterType::Pointer caster = CastFilterType::New();
  caster->SetInput(relabeler->GetOutput());


  try
    {
      caster->Update();
    }
  catch( itk::ExceptionObject & excep )
    {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << excep << std::endl;

    return EXIT_FAILURE;
    }

    std::cout << "Success" << std::endl;

    return EXIT_SUCCESS;

}

In Linux everything works fine.(Throws Description: itk::ERROR: itk::watershed::SegmentTreeGenerator::MergeSegments:: An unexpected and fatal error has occurred. This is probably the result of overthresholding of the input image.)

But in Windows the result of this code is unstable: It may crash, throw exception or give some segmentation(After running that code several times).
I’m using ITK’s 5.0.0 version.
Does anyone know about this problem.
I would be appreciate any help.
Thanks Hrach.

We refactored some internal of Watersheds. More information in this PR. Maybe that has something to do with the observed behavior?

dzenanz I checked and I have this changes in my ITK version.
And can not figure out what is the reason of this kind of undefined behaviour.
In contrast of Windows, Linux constantly throws exception.

For me, it consistently crashes in Visual Studio. I am looking into it.

The problem is that on line 169, (*segment_ptr).second.edge_list is empty, so .front() causes a crash. This probably indicates there is a problem in the previous filter in the pipeline, the WatershedSegmenter.

In 4.13.0 I have tested and there is no crash, either it compiles till the end or throws exception(An unexpected fatal error has occurred. This is probably the result of the overthresholding of the input image).
Is this fixed in 5.1.0 version?

No. I did my test with a recent master version, so this crash has not been fixed.

Than you.
How can I catch this, to not have a crash in the program?

And I want to figure out why doesn’t this crash in Linux?

Try running it in debug mode, maybe some assertions will be triggered.

As de-referencing a null pointer is undefined behavior, compiler usually assumes it will not happen and does optimizations under that assumption. This frequently leeds to no crash occurring in release mode even though it should. And different compilers do different optimizations, so undefined behavior manifests itself differently.

@dzenanz I have tested the same code in 4.13.0 and 5.0.0 with static builds.
In 4.13.0 it either throws exception or returns the image.
In contrast of 4.13.0, 5.0.0 time to time crashes the program.
Which files have been changed in 5.0.0 , which can cause this kind of behaviour?

There was a huge number of changes.

Dzenan@Ryzenator MINGW64 /c/Dev/ITK-git/Modules/Segmentation/Watersheds (master)
$ git diff 520a249306831f1acbc266caabc28a4a94e692de..833c1b8c47fa33364da00f089694144b3e419a75 . > c:/a/watersheds4_5.diff

watersheds4_5.diff (322.3 KB)
But as I said earlier, the most likely culprit is PR187.