Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: Clean up xout before rethrow #31

Merged
merged 2 commits into from Oct 18, 2017

Conversation

kaspermarstal
Copy link
Member

@kaspermarstal kaspermarstal commented Oct 7, 2017

Elastix did not call AfterRegistrationBase before throwing exception and consequently did not clean up xout. This resulted in undefined behaviour and more or less random segfaults if the ElastixFilter was called again after an exception was thrown. This would happen even if the filter was completely destroyed and a new filter was instantiated because xout is a global static object. This possibly fixes SuperElastix/SimpleElastix#123 and an issue previously reported by @coertmetz.

The PR needs more testing and thorough review before merge. In addition, we should review exception handling elsewhere - e.g. for transformix.

NOTE: This does not change the fact that elastix is not thread safe which might still be an issue (also reported by @coertmetz). The logger will most likely have to be completely refactored into a member variable on e.g. ElastixMain for the library interface to become thread safe.

Elastix did not call AfterRegistrationBase before throwing exception
and consequently did not clean up xout. This resulted in undefined
behaviour and more or less random segfaults if the ElastixFilter was
called again after an exception was thrown. This would happen _even_ if
the filter was completely destroyed and a new filter was instantiated.
This possibly fixes SuperElastix/SimpleElastix#123 and  an issue
previously reported by @coertmetz but need more testing. NOTE: This
does not change the fact that elastix is not thread safe which might
still be an issue (also reported by @coertmetz).
@coertmetz
Copy link
Collaborator

This seems to make a lot of sense. I do not have enough knowledge about AfterRegistrationBase to get an idea of possible side-effects however.

@mstaring
Copy link
Member

mstaring commented Oct 9, 2017

so AfterRegistrationBase() currently contains one line:

xl::xout.RemoveTargetCell( "iteration" );

I am not sure why this cell should be removed before throwing, but your explanation makes intuitive sense to me. At the least I see no harm in removing it, as this particular exception completely stops the registration altogether and (safely) terminates elastix.

@kaspermarstal Did you do a test with and without this change and indeed observed segfaults going away?
Is this test something that Coert could repeat?

@kaspermarstal
Copy link
Member Author

kaspermarstal commented Oct 9, 2017

Yes, @woutdenolf made a minimum working example with data in SuperElastix/SimpleElastix#123. You can get it there @coertmetz.

Yes, this patch fixes the problem on my machine -- I have not observed any segfault with the patch applied. However I have not been able to find out exactly what is going wrong when AfterRegistrationBase is not called. Sometimes it segfaults, sometimes it doesn't.

I can only assume that the logger somehow ends up in an inconsistent state if "iteration" is not removed -- but why or how I do not know.

@mstaring
Copy link
Member

Ok, so if it also works at Coert's side, then please go ahead with merging. In case Coert doesn't have time, go ahead with merging also.

@kaspermarstal
Copy link
Member Author

Is it something you plan to test @coertmetz?

@stefanklein
Copy link
Member

The iteration info output is of type xoutrow. And this is the only occasion where xoutrow is used. So maybe the underlying bug is in that class (could be, as it is the most complicated xout type). Maybe the destructor of xoutrow does not properly clean up itself for example.
To solve it, I think it might be better to call directly:
xl::xout.RemoveTargetCell( "iteration" );
instead of calling AfterRegistrationBase(). You in principle don't know what "AfterRegistrationBase" does more (currently nothing), which should not be done after an error has been thrown. Also, it would be unclear in the code why you call this function (since it is actually an indirect way to clean up xout; so, better to directly do that I think).

@coertmetz
Copy link
Collaborator

coertmetz commented Oct 17, 2017

Hi @stefanklein,

This is more or less what we now do at Quantib side as a work around. We catch the exceptions of elastix. In the catch block we do:

if (xoutlibrary::xout_valid()) {
    xoutlibrary::xout.RemoveTargetCell("iteration");
}

For this to work we added the xout_valid to the xoutlibrary. This method just checks if local_xout is not null:

bool xout_valid() {
  return local_xout != 0;
}

But of course, this should in principle be fixed within elastix.

…suggestd by @coertmetz, and do it directly, instead of AfterRegistrationBase as suggested by @stefanklein
@kaspermarstal kaspermarstal merged commit 57b17aa into develop Oct 18, 2017
@kaspermarstal kaspermarstal deleted the elx-make-elastix-libray-exception-safe branch October 18, 2017 11:34
@ascourtas
Copy link

to get these changes, would I need to rebuild the project, or is it sufficient to just pull down the updated repo?

@schmiedc schmiedc mentioned this pull request Nov 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Segmentation fault in AdaptiveStochasticGradientDescent::BeforeRegistration
5 participants