<div dir="ltr">A small correction to my discussion below: for DeleteEvent the calldata is a NULL pointer, not a vtkObject pointer.  The crash occurred when this NULL pointer was cast and dereferenced because the callback was expecting something else.</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Nov 3, 2016 at 7:21 AM, David Gobbi <span dir="ltr"><<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Okay, I think that I've found the problem.  The crash occurs when there is a mismatch between the calldata_type set for the callback, and the type of the actual calldata object passed at event invocation.<div><br></div><div>In TestInvokeEvent.py, when the DeleteEvent is invoked, the calldata is a vtkObject, so when the callback has been set to expect something else, there's a crash.  In other words, the test crashes simply because the callbacks are receiving events that the test's author didn't anticipate.</div><div><br></div><div>So Ken's earlier MR that modified the test is probably going in the right direction.  Since the callbacks in that test are expecting specific calldata types, they should be made to observe only the specific events that they expect.</div><div><br></div><div>I also think that TestInvokeEvent.py shouldn't use ModifiedEvent as the event to watch for.  For each calldata type, it should use an event type that usually uses calldata of that type.</div><div><br></div><div>For reference:</div><div><div><div><a href="https://gitlab.kitware.com/vtk/vtk/merge_requests/2135" target="_blank">https://gitlab.kitware.com/<wbr>vtk/vtk/merge_requests/2135</a><span class="HOEnZb"><font color="#888888"><br></font></span></div></div></div><span class="HOEnZb"><font color="#888888"><div><br></div><div> - David</div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 2, 2016 at 2:48 PM, David Gobbi <span dir="ltr"><<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">It looks like the fix didn't work.  But now that I know which dashboard is failing, and have seen the whole stack trace, I have a better idea of where the problem might be.  I'll give it another shot tonight.<span class="m_-7149696285115998997HOEnZb"><font color="#888888"><div><br></div><div> - David</div></font></span></div><div class="m_-7149696285115998997HOEnZb"><div class="m_-7149696285115998997h5"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 1, 2016 at 11:48 PM, David Gobbi <span dir="ltr"><<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>I wasn't able to reproduce the issue, but I think that I found out what causes it.  When vtkPythonCommand::Execute() is called, it tries to promote the subject object (i.e. the object being deleted for DeleteEvent) into a Python object.  I was able to confirm that this actually happens, and even though I couldn't get it to crash, I'm pretty sure that it puts the program into a bad state.</div><div><br></div><div>See <a href="https://gitlab.kitware.com/vtk/vtk/merge_requests/2131" target="_blank">https://gitlab.kitware.com/vtk<wbr>/vtk/merge_requests/2131</a></div><span class="m_-7149696285115998997m_5631681375367755946HOEnZb"><font color="#888888"><div class="gmail_extra"><br></div><div class="gmail_extra"> - David</div></font></span><div><div class="m_-7149696285115998997m_5631681375367755946h5"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 1, 2016 at 9:19 AM, Utkarsh Ayachit <span dir="ltr"><<a href="mailto:utkarsh.ayachit@kitware.com" target="_blank">utkarsh.ayachit@kitware.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Ken,<br>
<br>
The issue seems to be that the callback is attempted to be called for<br>
vtkCommand::DeleteEvent since the observer is set to respond to<br>
"AnyEvent".  When the object is being cleaned up as part of the<br>
interpreter being destroyed, calling Python commands is indeed<br>
problematic and hence the failure.<br>
<br>
The test can be fixed by changing the observer to only listen to<br>
ModifiedEvent instead of AnyEvent. Ideally vtkPythonCommand::Execute<br>
can check if the interpreter is being cleaned up, but I am not sure<br>
how to do that.<br>
<br>
Utkarsh<br>
<div><div class="m_-7149696285115998997m_5631681375367755946m_153474828382680764h5"><br>
On Tue, Nov 1, 2016 at 10:33 AM, Ken Martin <<a href="mailto:ken.martin@kitware.com" target="_blank">ken.martin@kitware.com</a>> wrote:<br>
> OK here is a puzzle. We have a test that is occasionally failing and I<br>
> suspect it fails due to random python order of deletion of vtk objects. The<br>
> relevant python code is below. It fails when unregistering a vtkObject and I<br>
> suspect it is failing when invoking an callback during the<br>
> unregisterinternal method see the stack trace. So maybe python has deleted<br>
> the object from its maps but then it gets used in a callback for another<br>
> object being deleted? Again my python foo is weak but maybe we have to<br>
> unregister the anyEvent observer before the end of the script? Maybe<br>
> something else?<br>
><br>
>     @vtk.calldata_type(vtk.VTK_OB<wbr>JECT)<br>
>     def callbackObj(self, caller, event, calldata):<br>
>         self.calldata = calldata<br>
><br>
>     def setUp(self):<br>
>         self.vtkObj = vtk.vtkObject()<br>
><br>
>         self.vtkObjForCallData = vtk.vtkObject()<br>
><br>
>     def test_obj(self):<br>
>         self.vtkObj.AddObserver(vtk.v<wbr>tkCommand.AnyEvent, self.callbackObj)<br>
>         self.vtkObj.InvokeEvent(vtk.v<wbr>tkCommand.ModifiedEvent,<br>
> self.vtkObjForCallData)<br>
>         self.assertEqual(self.calldat<wbr>a, self.vtkObjForCallData)<br>
><br>
> 0x7f98bd3e8770 : ??? [(???) ???:-1]<br>
> 0x7f98bd19b778 : vtkPythonCommand::Execute(vtkO<wbr>bject*, unsigned long, void*)<br>
> [(libvtkWrappingPython35Core-7<wbr>.1.so.1) ???:-1]<br>
> 0x7f98bcb9fd7e : ??? [(???) ???:-1]<br>
> 0x7f98bcba000c : vtkObject::UnRegisterInternal(<wbr>vtkObjectBase*, int)<br>
> [(libvtkCommonCore-7.1.so.1) ???:-1]<br>
> 0x7f98bd19f045 : vtkPythonUtil::RemoveObjectFro<wbr>mMap(_object*)<br>
> [(libvtkWrappingPython35Core-7<wbr>.1.so.1) ???:-1]<br>
> 0x7f98bd1a5b30 : PyVTKObject_Delete [(libvtkWrappingPython35Core-7<wbr>.1.so.1)<br>
> ???:-1]<br></div></div></blockquote></div></div></div></div></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>