Hi Jules, I think there is a race condition in Component, namely in how the Component::removeFromDesktop handles the peer member.
When a peer is removed from the desktop, the OS window is deleted and removed, but the peer member is never cleared. Normally,
the removeFromDesktop is called from the ctor of Component so it would not matter.
I am getting intermittent crashed when using Tootips in debug builds. It turns out that Component::removeFromDesktop is called from
TooltipWindow::hide on occasion. About 1:1000 this leads to a crash for me - in debug build. Particularly when creating /deleting / recreating tooltips in rapid succession.
The peer pointer is not zeroed, but since the content was deleted, it points to a lot of 0xfeeefeee
I think this can be remedied by simply zeroing the peer member after deletion in Component::removeFromDesktop
No, not that I’m aware of. The code that fails is 100% Juce. The tooltips are controlled somehow by a timer so that still imply the regular GUI thread is doing all the calls.
This happens way to seldom for me to be able to properly debug it.
I suppose the “race” comes from the apparent unsyncronized use of the peer member, that possibly can be undefined for a short period of time. Do you agree that it can be so?
No. There is no peer member variable in Component. I think you need to go back and have a re-think![/quote]
Ah, you are right. I never traced the origin of the variable long enough. I now see the heavyweight peers are stored in
a global Array that is accessed through some ComponentPeer statics.
The management of the lifetime of the ComponentPeer’s seem a bit too convoluted for my taste, at first glance, but I’m sure
there is a good reason why you did it this way. The ctor of ComponentPeer removes itself from the list in question. This is not a bullet proof
way of handling this however. No unsyncronized access should happen if all GUI access is done in the same thread…
However, something does happen.
In Component::setBounds(const int x, const int y, int w, int h)
call to
peer->setBounds (getX(), getY(), getWidth(), getHeight(), false);
call to
repaintNowIfTransparent();
call to
isUsingUpdateLayeredWindow()
crash on
! component.isOpaque(); (where component is invalid)
At some point, the contents of the ComponentPeer is all 0xfeeefeee but I don’t know when and where this happens. It’s almost like the
peer is deleted somewhere in there.
Hmm. I suppose if you were to delete your component or its peer in response to a size change or movement, then it could be called with a dangling pointer…
[quote=“jules”]Hmm. I suppose if you were to delete your component or its peer in response to a size change or movement, then it could be called with a dangling pointer…
Try this:
void repaintNowIfTransparent()
{
if (isValidPeer (this)
&& isUsingUpdateLayeredWindow() && lastPaintTime > 0 && Time::getMillisecondCounter() > lastPaintTime + 30)
handlePaintMessage();
}
[/quote]
Alright, this may aid a bit. The problem occur so seldom so it may take a day or two until it happens again. I’ll be back. Thanks Jules.