From: Kevin Ollivier <kev...@theolliviers.com>
Date: Thu, 20 Sep 2012 09:17:20 -0700
Local: Thurs, Sep 20 2012 12:17 pm
Subject: Re: [wxPython-dev] Segmentation faults - a theory
Hi Sam,
On Sep 20, 2012, at 4:27 AM, Sam Partington wrote:
> Hi Kevin,
There is a reason there are no pure Python GUIs. All the safety checks Python runs make it impossible to write code that needs to be as fast and tight as GUI code needs to be. You can call that a cop out if you like, but it's a plain fact. Slowing down Destroy() is probably not a huge deal, but if you really want wxPython never to be able to crash under any circumstance, you will indeed need to slow it to the point where it is no longer usable speed-wise.
> On 20 September 2012 06:20, Kevin Ollivier <kev...@theolliviers.com> wrote:
> Any extension can crash. No extension should crash. I have no idea
> You don't know if my proposed fix will slow down wxPython at all, let
If it's more or less impossible for you to know how and where your code is being called, I think that is a (perhaps the) problem.
> alone noticeably. Until you have measured the slow down there is no > way you can decide whether the pay off is worth it or not. If it does > turn out to be significantly slower then we could certainly make it a > build time option, and so let the user of the library decide, assuming > they are happy to build their own version of wxPython, we already do > this because when we find and fix bugs in wxPython we can't wait for > the wxPython release cycle to incorporate our fixes (note that I'm > most definately not complaining here, just stating the facts). We do > submit all bug fixes upstream. > In any case, for the software that my company writes, I would accept a
>>>> In short, use wx.CallAfter or preferably re-design your approach so that you do
>>> As I said in my other reply to Robin, you just don't know that you are
>> The solution is simple - do not do deletion inside event handlers. Schedule them for deletion later. C++ programmers can't do this without getting segfaults either, BTW. ;-)
> You've clearly not read what I wrote in that paragraph which is that
> As the application complexity increases the likelihood of these things
It is more correct to say "we didn't realize our code was doing that", but that still means it did do it. > taking place increases. > It is, BTW, completely irrelevant that C++ can cause crashes in the
>>> Often
>>> It's a hack, and I am 99% certain that we have not fixed all of our
>> It's not really a hack, it's how you handle this use case. There are just certain things you should not do inside event handlers.
> See above, we didn't (directly).
>> Bottom line is that modifying Destroy() on the Python side would
The API does, and is designed to, delete the control. There is no better indication of "use with caution" than that. As Peter said, and was quite right about, you ARE using a C++ API, even if you are using it from Python. Python does not have methods like this because they use ref-counting for everything. C++ and wxWidgets sometimes use an object ownership model instead, and that is the case here.
>> probably not be welcomed because it can cause behavior changes >> in existing apps for whom Destroy() is working as expected. Under >> the hood behavior changes of this nature for APIs really only make >> sense when they are fundamentally broken. Destroy() not working in >> event handlers is not really brokenness from the perspective that it >> is not meant to be called from them in the first place, in Python or >> C++ or any language. (Perhaps a note to this effect in the docs >> would be welcomed, though.) > I am amazed that you think that the current API of wxPython crashing
> My proposed fix is to detect Destroy being called from within an event
Turning an expected Destroy() crash into an exception, provided that you can *always* perfectly determine when Destroy() is going to lead to a crash, is probably not a harmful change. However, that's the sort of change that sounds like it would use some sort of heuristics for determining where it is called from (perhaps parsing a stack trace?), which is probably very tough to get right, and may very well lead to exceptions being thrown when the programmer knows what they're doing and is calling the API in a safe and valid way. Or, also, in some limited cases calling from an event handler may be perfectly acceptable, such as, say, a menu event handler or a user-defined event, which we would now likely forbid. Prediction is very, very hard to get right unconditionally.
> handler and only then to behave differently. I have not yet decided > whether that should then raise an exception or defer the Destroy. > Perhaps in this case explicit is better than implicit. > Yes this would be a behaviour change, but one that I think most users
> API : Call destroy (directly, or indirectly) from an event handler:
> Current behaviour: crash your app.
> I find it hard to imagine that there are many users who would be upset
In addition, altering Destroy() in this way doesn't help anyone who may trigger a crash, just this specific case, so it's usefulness is limited as well. A more general fix for crashes is probably a much better option. For example, this may more or less solve the problem for you, and not only apply to the Destroy() case, but any possible crash scenario:
http://pypi.python.org/pypi/faulthandler/
In fact, this was included in Python as of 3.3, w00t! :) If this module is reliable (and inclusion suggests it has at least been vetted), I personally would be in favor of including something like this in wxPython, at least for versions < 3.3, as getting a stack trace when a crash does happen is pretty nice, IMHO, and makes tracking down crashes and fixing them much simpler.
Now, deferring the Destroy(), on the other hand, is not just an error catch but a behavior change, and the only way to defer it reasonably would be to make it asynchronous. That means that, for everyone calling it, the Destroy() will now happen at some unknown time. That, to me, is scary. If your wx event queue gets really backed up, it could delay the call for several seconds. In the meantime, code expecting the control to be deleted may run, which could cause any number of unexpected behaviors. This is especially possible if the code has many abstraction layers, as you well know. :)
Regards,
Kevin
> Sam
> -- You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
| ||||||||||||||