Paraview vtkClientServerInterpreter can be uninitialized in some circumstances (delete + new at the same address)
Version affected: verified on 3.14, but the same code is present in 5.1, so I expect a similar behavior.
I experienced occasional crashes in our product's testsuite resulting in the following (or similar) message
vtkSIProxy (0x7e23040): Failed to create vtkPolyDataMapper. Aborting for debugging purposes.
/home/travis/build.sh: line 45: 4392 Aborted
I was able to track down the problem to an uninitialized vtkClientServerInterpreter, specifically the fact that the generated Init functions (see ParaView-3.14.1-Source/Utilities/VTKClientServer/Wrapping/vtkWrapClientServer.c
and equivalent in ParaView 5.1) creates as:
1043 fprintf(fp,"void %s_Init(vtkClientServerInterpreter* csi);\n",classes[i]);
1044 }
1045 fprintf(fp,
1046 "\n"
1047 "//-------------------------------------------------------------------------auto\n"
1048 "void VTK_EXPORT %s_Init(vtkClientServerInterpreter* csi)\n"
1049 "{\n"
1050 " static vtkClientServerInterpreter* last = NULL;\n"
1051 " if(last != csi)\n"
1052 " {\n"
1053 " last = csi;\n", data->ClassName);
1054 for (i=0; i < totalClasses; ++i)
1055 fprintf(fp," %s_Init(csi);\n",classes[i]);
1056 if(!data->IsAbstract)
1057 fprintf(fp," csi->AddNewInstanceFunction(\"%s\", %sClientServerNewCommand);\n",
1058 data->ClassName,data->ClassName);
1059 fprintf(fp," csi->AddCommandFunction(\"%s\", %sCommand);\n",
1060 data->ClassName,data->ClassName);
1061 fprintf(fp, " }\n}\n");
The problematic code is the resulting output code:
static vtkClientServerInterpreter* last = NULL;
if(last != csi)
This code skips the registration of the new instance function if the passed ClientServerInterpreter pointer is the same as the previously done (whose pointer is stored as a static local variable). This has probably been made to prevent double initialization. Unfortunately, the comparison of pointers does not consider the possibility that the Interpreter has been deleted and reinstantiated again, and it also happens to be at the exact same memory address. The comparison will therefore skip the initialization and the Interpreter will be left uninitialized, resulting in the abort() given above.
Not being well versed in the underlying design, I am unable to say if this is a bug or an intentional choice that is exposed by some incorrect usage upstream, but my testing code is not doing anything complicated: simply calling paraview.simple.Connect and Disconnect many times.
Please let me know if any more relevant information is needed. A few more details on the investigation are available here.