[vtk-developers] InvokeEvent test randomly failing quiz

David Gobbi david.gobbi at gmail.com
Thu Nov 3 09:49:46 EDT 2016


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.

On Thu, Nov 3, 2016 at 7:21 AM, David Gobbi <david.gobbi at gmail.com> wrote:

> 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.
>
> 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.
>
> 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.
>
> 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.
>
> For reference:
> https://gitlab.kitware.com/vtk/vtk/merge_requests/2135
>
>  - David
>
> On Wed, Nov 2, 2016 at 2:48 PM, David Gobbi <david.gobbi at gmail.com> wrote:
>
>> 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.
>>
>>  - David
>>
>> On Tue, Nov 1, 2016 at 11:48 PM, David Gobbi <david.gobbi at gmail.com>
>> wrote:
>>
>>> 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.
>>>
>>> See https://gitlab.kitware.com/vtk/vtk/merge_requests/2131
>>>
>>>  - David
>>>
>>> On Tue, Nov 1, 2016 at 9:19 AM, Utkarsh Ayachit <
>>> utkarsh.ayachit at kitware.com> wrote:
>>>
>>>> Ken,
>>>>
>>>> The issue seems to be that the callback is attempted to be called for
>>>> vtkCommand::DeleteEvent since the observer is set to respond to
>>>> "AnyEvent".  When the object is being cleaned up as part of the
>>>> interpreter being destroyed, calling Python commands is indeed
>>>> problematic and hence the failure.
>>>>
>>>> The test can be fixed by changing the observer to only listen to
>>>> ModifiedEvent instead of AnyEvent. Ideally vtkPythonCommand::Execute
>>>> can check if the interpreter is being cleaned up, but I am not sure
>>>> how to do that.
>>>>
>>>> Utkarsh
>>>>
>>>> On Tue, Nov 1, 2016 at 10:33 AM, Ken Martin <ken.martin at kitware.com>
>>>> wrote:
>>>> > OK here is a puzzle. We have a test that is occasionally failing and I
>>>> > suspect it fails due to random python order of deletion of vtk
>>>> objects. The
>>>> > relevant python code is below. It fails when unregistering a
>>>> vtkObject and I
>>>> > suspect it is failing when invoking an callback during the
>>>> > unregisterinternal method see the stack trace. So maybe python has
>>>> deleted
>>>> > the object from its maps but then it gets used in a callback for
>>>> another
>>>> > object being deleted? Again my python foo is weak but maybe we have to
>>>> > unregister the anyEvent observer before the end of the script? Maybe
>>>> > something else?
>>>> >
>>>> >     @vtk.calldata_type(vtk.VTK_OBJECT)
>>>> >     def callbackObj(self, caller, event, calldata):
>>>> >         self.calldata = calldata
>>>> >
>>>> >     def setUp(self):
>>>> >         self.vtkObj = vtk.vtkObject()
>>>> >
>>>> >         self.vtkObjForCallData = vtk.vtkObject()
>>>> >
>>>> >     def test_obj(self):
>>>> >         self.vtkObj.AddObserver(vtk.vtkCommand.AnyEvent,
>>>> self.callbackObj)
>>>> >         self.vtkObj.InvokeEvent(vtk.vtkCommand.ModifiedEvent,
>>>> > self.vtkObjForCallData)
>>>> >         self.assertEqual(self.calldata, self.vtkObjForCallData)
>>>> >
>>>> > 0x7f98bd3e8770 : ??? [(???) ???:-1]
>>>> > 0x7f98bd19b778 : vtkPythonCommand::Execute(vtkObject*, unsigned
>>>> long, void*)
>>>> > [(libvtkWrappingPython35Core-7.1.so.1) ???:-1]
>>>> > 0x7f98bcb9fd7e : ??? [(???) ???:-1]
>>>> > 0x7f98bcba000c : vtkObject::UnRegisterInternal(vtkObjectBase*, int)
>>>> > [(libvtkCommonCore-7.1.so.1) ???:-1]
>>>> > 0x7f98bd19f045 : vtkPythonUtil::RemoveObjectFromMap(_object*)
>>>> > [(libvtkWrappingPython35Core-7.1.so.1) ???:-1]
>>>> > 0x7f98bd1a5b30 : PyVTKObject_Delete [(libvtkWrappingPython35Core-7
>>>> .1.so.1)
>>>> > ???:-1]
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20161103/dc93b004/attachment-0001.html>


More information about the vtk-developers mailing list