wxPython 4.0.0a1/a2 GC.GetTextExtent hang on exit

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

wxPython 4.0.0a1/a2 GC.GetTextExtent hang on exit

Florian Höch
I recently ran into very sporadic and hard to reproduce hangs and
segfaults (installing faulthandler sometimes prints "GC object already
tracked") with an application that runs fine with wxPython classic 3.0.2
(Win10 64-bit, Python 2.7 32-bit). After lots of poking, I tracked it
down to the OnPaint handler of wx.lib.gradientbutton.GradientButton,
more specifically, the call to gc.GetTextExtent therein (other stuff
that calls gc.GetTextExtent is affected as well). The hang/segfault can
be avoided by replacing GraphicsContext.GetTextExtent calls with
self.GetTextExtent, or using wxPython Classic instead.

I've since tried to come up with a reproducible test case, which turned
out to be challenging due to the even more sporadic nature of the
problem when isolated, but have hopefully succeeded.


Condition: For the hang/segfault to happen, there need to be calls to

GraphicsContext.GetTextExtent in the UI thread, and there needs to be a
background thread
 that actually does something, even if it is just sleep()-ing, and
creates some load. The more happens in the background thread, the more
likely the problem occurs.

The attached script, when run without arguments for a while (say, a
minute), should reproducibly hang after closing the main window when
using wxPython 4.0.0a1/a2 and Python 2.7 32-bit under Windows (10 in my
case, but I would assume the Windows version doesn't really matter, and
probably also the Python version). I have not tested under other systems.

You can run the script with the argument `wxbutton` to prevent the hang,
which will make it use wx.Button instead of GradientButton, or with the
argument `fix` to override GraphicsContext.GetTextExtent.

Some notes:
DO NOT run this test on a single core machine. It will bog down the system.


To make the hang/segfault more likely, the number of elements
dynamically calling GraphicsContext.GetTextExtent is increased far
beyond reasonable limits
 and split across several dialogs with timers that change the state and
visual appearance of the elements in periodic intervals, to increase the
amount of GraphicsContext.GetTextExtent calls.

I would assume this will need fixing in the wxPython C++ codebase.

--
Florian Höch

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

wx40a2_GC_GetTextExtent_hang_on_exit.py (7K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wxPython 4.0.0a1/a2 GC.GetTextExtent hang on exit

Robin Dunn
Thanks.  It was an issue with the GIL.

https://github.com/wxWidgets/Phoenix/issues/353
https://github.com/wxWidgets/Phoenix/pull/354

Robin


Florian Höch wrote:

> I recently ran into very sporadic and hard to reproduce hangs and
> segfaults (installing faulthandler sometimes prints "GC object already
> tracked") with an application that runs fine with wxPython classic 3.0.2
> (Win10 64-bit, Python 2.7 32-bit). After lots of poking, I tracked it
> down to the OnPaint handler of wx.lib.gradientbutton.GradientButton,
> more specifically, the call to gc.GetTextExtent therein (other stuff
> that calls gc.GetTextExtent is affected as well). The hang/segfault can
> be avoided by replacing GraphicsContext.GetTextExtent calls with
> self.GetTextExtent, or using wxPython Classic instead.
>
> I've since tried to come up with a reproducible test case, which turned
> out to be challenging due to the even more sporadic nature of the
> problem when isolated, but have hopefully succeeded.
>
>
> Condition: For the hang/segfault to happen, there need to be calls to
>
> GraphicsContext.GetTextExtent in the UI thread, and there needs to be a
> background thread
>  that actually does something, even if it is just sleep()-ing, and
> creates some load. The more happens in the background thread, the more
> likely the problem occurs.
>
> The attached script, when run without arguments for a while (say, a
> minute), should reproducibly hang after closing the main window when
> using wxPython 4.0.0a1/a2 and Python 2.7 32-bit under Windows (10 in my
> case, but I would assume the Windows version doesn't really matter, and
> probably also the Python version). I have not tested under other systems.
>
> You can run the script with the argument `wxbutton` to prevent the hang,
> which will make it use wx.Button instead of GradientButton, or with the
> argument `fix` to override GraphicsContext.GetTextExtent.
>
> Some notes:
> DO NOT run this test on a single core machine. It will bog down the system.
>
>
> To make the hang/segfault more likely, the number of elements
> dynamically calling GraphicsContext.GetTextExtent is increased far
> beyond reasonable limits
>  and split across several dialogs with timers that change the state and
> visual appearance of the elements in periodic intervals, to increase the
> amount of GraphicsContext.GetTextExtent calls.
>
> I would assume this will need fixing in the wxPython C++ codebase.
>


--
Robin Dunn
Software Craftsman
http://wxPython.org

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Loading...