Opened 18 years ago
Last modified 18 years ago
#34 assigned defect
Spontaneous traps of Qt applications during window management
Reported by: | dmik | Owned by: | dmik |
---|---|---|---|
Priority: | normal | Milestone: | qt-os2-3.3.1-rc07 |
Component: | kernel | Version: | 3.3.1-rc06 |
Severity: | normal | Keywords: | |
Cc: |
Description
Sometimes, a Qt application just traps in the middle of some window management (assumption). On my system, it happened a couple of times with Psi/2 upon attempts to show tooltips.
Change History (4)
comment:1 by , 18 years ago
Status: | new → assigned |
---|
comment:2 by , 18 years ago
According to the disassembly, QObject::parent() does mov eax, [eax + 0x0C]
, but eax (this pointer) is 0xFFFFFFFF there, resulting into a typical access violation. Tracking the stack down, I see that this pointer is a result of calling parentWidget() on a QWidget pointer taken from the QWL_QTMODAL window word in QtFrameWindow().
Two reasons can cause this:
- Window data is not initialized to 0 when the widget is created, so we get garbage when reading it before it was set/reset by a modal widget.
- qt_dispatchBlocked(), when leaving the modal state for a given modal widget, skips some widgets that it previously set as being blocked by the given modal widget (by storing the address of the modal widget in QWL_QTMODAL). As a result, the modal widget is deleted but other widgets still refer to it through their QWL_QTMODAL word.
Reason 1 is unlikely (I have never seen anything but 0 there after window creation; I'm quite sure PM does memset(ptr,0,len). However, I haven't found any information confirming that in PMREF, so it's more correct to set all window data to zero ourselves.
Reason 2 is hardly reproduceable, however, there is a !isHidden() check done when widgets are marked as being blocked/unblocked. It means that if the widget was hid after it has been blocked, but not shown again before the modal that made it bloced went away, it would never be unblocked. Well, it's quite possible in reality I think.
comment:3 by , 18 years ago
Also, it's theoretically possible that other widget flags (involved in to the decision whether to block or not) are changed. It's however and should never happen (only reparentSys() is allowed to change flags of the existing widget), but QWidget::setWFlags is a public method, so...
comment:4 by , 18 years ago
Both reasons should have been fixed now by changeset:153. I'll see if it was correct by testing it with Psi.
Thanks to our new exception handling, both times I've got the following call stack: