From: Tim E. R. <ter...@ro...> - 2011-10-12 08:53:20
|
> > On Tue, Oct 11, 2011 at 11:12 PM, Tim E. Real wrote: > > > Hey folks. > > > > > > Hey Florian, been studying those two crash traces you posted. > > > > > > In the course of trying to reproduce them, I've found > > > a nasty puzzling bug. > > > > > > They may all be related, possibly mixed in with some > > > negligence in my memleak fixes. > > > > > > Can you guys test the attached simple file? > > > (It's one midi track containing one blank part, with its PianoRoll > > > open - it has to be open and saved like that for this bug to appear.) > > > > > > Simple steps to reproduce: > > > Open the file. > > > Now, without closing muse, open the file again (I use re-open). > > > > > > Poof. Gone. Segfault. Am I right? > > > If not true then let me know! And Ignore the rest of this. > > > > > > The cause is disturbing, I'm stuck! > > > > > > In MusE::clearSong() where it closes all TopWins with the line: > > > > > > tl->close(); > > > > > > the TopWins are not being deleted upon closing !! > > > > > > Yep, so upon reloading the file, the existing PianoRoll is still > > > alive after closing it, so then in Song::clear() upon this line: > > > > > > emit songChanged(-1); > > > > > > the zombie PianoRoll responds to the signal and crashes because > > > its current part does not exist - it was deleted earlier along with > > > everything else, during this song clearing portion. > > > (Remember, to exist an editor *must* have associated part(s), > > > that's why they destroy themselves when you delete part(s). ) > > > > > > I examined the window attributes just before closing and yes, > > > WA_DeleteOnClose is still set. > > > > > > No destructor called, nothing. The darn TopWins just refuse to go away ! > > > I tried everything including increasing the time delay just after closing > > > in MusE::clearSong(), by ten-fold. > > > > > > Here's the weird part: If the window (the PianoRoll) is closed with > > > the "X", guess what - it /does/ delete itself and everything is fine. > > > (Try it - close the PianoRoll before you open my file again.) > > > > > > So the TopWins refuse to die if close() 'd but die if "X" 'd. > > > > > > I observed a couple of trips to MuseApplication::notify() > > > just after close() is called. > > > Maybe something is stopping the deletion in there... > > > > > > Anyway here's the fix: > > > In MusE::clearSong just after the line whre it closes the TopWins: > > > > > > tl->close(); > > > delete tl; // <- I added this line > > > > > > It works. Further proof the windows aren't deleting themselves, > > > otherwise that line would crash it. > > > > > > Something fishy going on... Later. Tim. > > > > > > > > > > Hmm QWidget::close() is a slot according to Qt. I am not sure how > > valid it is to call a slot directly from a regular function. > No trouble. Just 'cause it's a slot makes no difference. > Close() is just the programmatic way of closing a window. > > In case you were wondering, forgot to mention: > Yes, the widget (PianoRoll) overrides ::closeEvent(QCloseEvent* e), > but it properly calls e->accept(). > And the boolean result of the close() is true, so no problems there, > the widgets /are/ closing. Just not destroying. > > Again, this is why it's weird. They /are/ closing but refusing to destroy. > So nothing is hijacking the close event down the line and setting > it to 'ignore()' for example. > Something is however, I think hijacking the WA_DeleteOnClose > attribute : > > In MusE::clearSong immediately before tl->close() is called, > the result of this is true: > > tl->testAttribute(Qt::WA_DeleteOnClose); > > Immediately after close() is called, the result is false ! > (That's with original code, meaning the widget is still alive after close.) > > I get a sneaky feeling something resets the attribute just before Qt > gets around to examining it to see if the widget should be deleted. > > I am sure this fundamental operation was working up to very recently. > PS You didn't say whether the file worked. I guess later. NP. > Cheers. Tim. > > > Since it > > is a slot, maybe it is waiting for the event loop to complete (just a > > guess). Do we really need to close() it? Maybe there is an alternative > > method. Sorry, on second troll you are right, it is delayed. But it still doesn't answer why calling close() is resetting the attribute. That's crazy, wouldn't you think? And the fact is, when close() is called the widget isn't being deleted at all, now or later. Reading some more, it may have something to do with these widgets being QMainWindow, yet having parents. http://lists.trolltech.com/qt-interest/2008-04/msg00371.html Very similar problem there, except it implies that the poster observed the widget eventually deleting later. Here I don't. The response says it is best to use WA_DeleteOnClose for parent-less widgets. This is what Help only very weakly implies, but does not specifically say is limited to. I dunno, MusE has worked like this for a long time I can say up until recently. I'm purdy sure the techniques used are (mostly) OK. Deleting upon closing is such a fundamental feature of toolkits. Here it is required. The widget must destroy when "X" is clicked or when close() is called. I can explain why later. It should not matter whether it has a parent or not, it should 'just go'. If I must inform the parent so that only it then destroys the child, or something like that, that seems too bizarre, especially closing via "X". I may try a test mockup to see if I can isolate this. Well I've learned when I ramble on this much, it's usually something simple or overlooked, way different. Til' tomorrow. Tim. > > > > Orcan > |