PETScSNESSolver crashes when initialised and deleted without being used
Run this few times (crashes are random):
from fenics import PETScSNESSolver
solver = PETScSNESSolver()
del solver
The problem is a PETSc raw Vec
, called f_tmp
, which is not initialised but it is destroyed by the destructor. Now, this is actually odd, because VecDestroy
tries to deallocate the memory even if the vector has not been VecCreate
d, and that's because the pointer (Vec
is a pointer in PETSc internals) looks valid.
The solution is simple, i.e. set it to NULL
during the construction:
diff --git a/dolfin/nls/PETScSNESSolver.cpp b/dolfin/nls/PETScSNESSolver.cpp
index 532df94..5a37c9c 100644
--- a/dolfin/nls/PETScSNESSolver.cpp
+++ b/dolfin/nls/PETScSNESSolver.cpp
@@ -124,6 +124,7 @@ PETScSNESSolver::PETScSNESSolver(std::string nls_type) :
_snes_ctx.nonlinear_problem = NULL;
_snes_ctx.xl = NULL;
_snes_ctx.xu = NULL;
+ _snes_ctx.f_tmp = NULL;
// Check that the requested method is known
if (_methods.count(nls_type) == 0)
You can reproduce the problem outside DOLFIN with the following code (if you uncomment the commented line it works):
#include <petsc.h>
struct mysolver { Vec f; };
int main(void)
{
PetscInitializeNoArguments();
std::unique_ptr<mysolver> s(new mysolver);
//s->f = NULL;
if (s->f != NULL) VecDestroy(&s->f);
PetscFinalize();
return EXIT_SUCCESS;
}
Comments (4)
-
-
We need this fix. I implemented a destructor and constructor to the private class (struct).
Also the snes_ctx_t is needed to keep track of the original PETScVector, apparently for updating ghost values. Have a look at the comments in:
PETScSNESSolver::FormFunction
-
- changed status to resolved
Fixed in: a2e03548dc52b5f0c15394efaeb00ad01ec346df
-
- removed milestone
Removing milestone: 1.5 (automated comment)
- Log in to comment
The initialisation of
_snes_ctx
member data should be done in asnes_ctx_t
constructor. It should also have a destructor.That said, I can't see from the code in
PETScSNESSolver
why we needsnes_ctx_t
.