Open tsieger opened 10 years ago
Similar behaviour experienced when using the master branch and building against Qt5.2.0 (still R 3.1.0, Win7 SP1 32bit). The characterWidget.R
demo crashes while painting the grid:
> library(qtpaint)
Loading required package: qtbase
Learn more about Qt at http://qt.nokia.com
warning: Invalid parameter passed to C runtime function.
[New Thread 2712.0xb8c]
> source('/src/qtbase-141013-win32-fixes/qtbase/demo/characterWidget.R')
qt_qnewMetaObject() superdata: 62170064 QWidget
// content:
7, // revision
0, // classname
0, 14, // classinfo
1, 14, // methods
0, 19, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
1, // signal count
// signals: name, param-count, typeinfo-offset, tag, flags
1, 1, 19, 3, 0x46
// properties: name, type, flags
// notifies: signal
// typeinfo: name, [param_type]*, [param_name]*
43, 10, 2,
qt_meta_stringdata:
"R::.GlobalEnv::CharacterWidget"
"characterSelected"
"character"
""
[New Thread 2712.0xf2c]
[New Thread 2712.0xb0c]
[New Thread 2712.0xc28]
[New Thread 2712.0xca4]
Program received signal SIGSEGV, Segmentation fault.
0x61c02cfb in ZN18QRasterPaintEngine17ensureRasterStateEv () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
(gdb) bt
#0 0x61c02cfb in ZN18QRasterPaintEngine17ensureRasterStateEv () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
#1 0x00000000 in ?? ()
Another attempt gives a stack trace:
Program received signal SIGSEGV, Segmentation fault.
0x61c02cfb in ZN18QRasterPaintEngine17ensureRasterStateEv () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
(gdb) bt
#0 0x61c02cfb in ZN18QRasterPaintEngine17ensureRasterStateEv () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
#1 0x0000001b in ?? ()
#2 0x049b3898 in ?? ()
#3 0x07660604 in __smokeqt::x_QPainter::x_99(Smoke::StackItem*) () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#4 0x07507ca0 in __smokeqt::xcall_QPainter(long, void*, Smoke::StackItem*) () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#5 0x0746e457 in SmokeMethod::invoke(SmokeObject*, Smoke::StackItem*) () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#6 0x074700e1 in MethodCall::invokeMethod() () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#7 0x0746fffc in MethodCall::marshal() () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#8 0x07470182 in MethodCall::eval() () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#9 0x0746e2c1 in ForeignMethod::invoke(SEXPREC*, SEXPREC*) () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#10 0x075dbf74 in SmokeMethod::invoke(SEXPREC*, SEXPREC*) () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#11 0x0746f453 in DynamicBinding::invoke(SEXPREC*, SEXPREC*) () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#12 0x07469bc1 in qt_qinvoke () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#13 0x6c81c612 in Runzip () from C:\Program Files\R\R-3.1.0\bin\i386\R.dll
#14 0x04b2b7f4 in ?? ()
#15 0x048d24a0 in ?? ()
Cannot access memory at address 0x40000017
The sliders.R
demo crashes after a while:
Program received signal SIGSEGV, Segmentation fault.
0x619438ad in ?? () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
Probably related to the event loop issues. Too many threads.
Do you think it can be solved (in near future)? Or would some workaround help temporarily?
It's weird how the trace (in both the 4.8 and 5.2 cases) start with the seemingly unrelated Runzip(). First would be to confirm the multi-thread hypothesis. One way would be to modify the paintEvent callback in that characterWidget demo to just print a debug message and then enter an infinite loop. If there is one thread, it should print the message only once. It could be that there is actually something wrong with QPainter, or how we are using it.
Trying the test you propose I can see the debug print from within the modified qpaintEvent
just once. Then, after a while (I can see some characters drawn by the mouseMoveEvent
in the meantime), R crashes.
The same happens if I disable the call to qsetMethod("paintEvent", ...
completely, e.g.:
> library(qtbase);source('C:/src/qtbase-141013-win32-fixes/qtbase/demo/charact$
[New Thread 2040.0xd14]
[...MOC debugs omitted...]
[New Thread 2040.0x774]
[New Thread 2040.0xcec]
[New Thread 2040.0x84c]
> [New Thread 2040.0xa04]
[New Thread 2040.0x8fc]
Program received signal SIGSEGV, Segmentation fault.
0x61df0cca in ZNK7QWidget14backgroundRoleEv () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Widgets.dll
(gdb) Exception condition detected on fd 0
error detected on stdin
Yea, I'm pretty sure this is just due to accidental multi-threading and race conditions. The intern at Amazon tried to fix this by basically being more aggressive about updating in sync with R, but I think even Qt does not fare well when there are multiple threads. One test would be to run something via Rscript, i.e., something without the R Windows GUI. I'm pretty sure it's the Windows GUI that somehow drives the Qt event loop in a different thread.
Previously, I did not use R win GUI, but Rterm.exe. However, the problem persists even when running via Rscript. It seems that the Qt event loop gets driven in thread 5, while the painter is active in thread 1.
Thread 1:
Program received signal SIGSEGV, Segmentation fault.
0x61c02cfb in ZN18QRasterPaintEngine17ensureRasterStateEv () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
(gdb) bt
#0 0x61c02cfb in ZN18QRasterPaintEngine17ensureRasterStateEv () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
#1 0x00000005 in ?? ()
#2 0x0c64f850 in ?? ()
#3 0x06c40604 in __smokeqt::x_QPainter::x_99(Smoke::StackItem*) () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#4 0x06ae7ca0 in __smokeqt::xcall_QPainter(long, void*, Smoke::StackItem*) () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#5 0x06a4e457 in SmokeMethod::invoke(SmokeObject*, Smoke::StackItem*) () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#6 0x06a500e1 in MethodCall::invokeMethod() () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#7 0x06a4fffc in MethodCall::marshal() () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#8 0x06a50182 in MethodCall::eval() () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#9 0x06a4e2c1 in ForeignMethod::invoke(SEXPREC*, SEXPREC*) () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#10 0x06bbbf74 in SmokeMethod::invoke(SEXPREC*, SEXPREC*) () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#11 0x06a4f453 in DynamicBinding::invoke(SEXPREC*, SEXPREC*) () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#12 0x06a49bc1 in qt_qinvoke () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#13 0x6c81c612 in Runzip () from c:\Program Files\R\R-3.1.0\bin\i386\R.dll
#14 0x04d56c00 in ?? ()
#15 0x024a24a0 in ?? ()
Cannot access memory at address 0x40000017
Thread 5:
#0 0x774c70b4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
#1 0x75d24f51 in USER32!GetSystemMenu () from C:\Windows\system32\user32.dll
#2 0x75d21953 in USER32!GetNextDlgTabItem () from C:\Windows\system32\user32.dll
#3 0x75d1ada9 in USER32!SetClassLongW () from C:\Windows\system32\user32.dll
#4 0x06a41802 in run_callback() () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#5 0x06a41a57 in callback_input_handler() () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#6 0x06a416a7 in EventLoop::run() () from c:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#7 0x68895319 in ZN7QThread21setTerminationEnabledEb () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#8 0x75e898da in msvcrt!free () from C:\Windows\system32\msvcrt.dll
#9 0x5b1ba4fe in ?? ()
#10 0x04a05058 in ?? ()
#11 0x75e91287 in msvcrt!_itow_s () from C:\Windows\system32\msvcrt.dll
#12 0x75e91328 in msvcrt!_endthreadex () from C:\Windows\system32\msvcrt.dll
#13 0x75c73c45 in KERNEL32!AcquireSRWLockExclusive () from C:\Windows\system32\kernel32.dll
#14 0x774e37f5 in ntdll!RtlInsertElementGenericTableAvl () from C:\Windows\system32\ntdll.dll
#15 0x774e37c8 in ntdll!RtlInsertElementGenericTableAvl () from C:\Windows\system32\ntdll.dll
#16 0x00000000 in ?? ()
That's actually on purpose. We run our own thread that is synchronized with the R event loop in thread 1. It should not cause any trouble. So many this bug is pointing at something deeper; it's just so hard to disentangle things when errors happen within Qt, and only on Windows.
I'm ready to help with testing, limited debugging etc.
Do you have the process for building it documented somewhere? I will just follow that and start debugging things. Thanks!
Thanks! Basically, I followed https://github.com/ggobi/cranvas/wiki/Installation-under-windows-32-bit. Exceptions to these instructions included:
i) do not use g++ from RTools, but from MinGW, preferrably the one coming with/binary compatible with Qt. It seems that Qt 4.x (at least 4.8.2) asks for a specific version of MinGW. Qt 5.x (at least 5.2.1) comes with its own copy of MinGW (not sure if it gets installed by default).
ii) if you run into linking problems of multiple definition of _head_Qt5PrintSupport_dll
, _head_Qt5XmlPatterns_dll
, and _head_Qt5Test_dll
, you may want to disable support for the Test
, PrintSupport
, and XmlPatterns
Qt modules in CMakeFiles.txt
in src
and
kde-bindings/smoke/qt
, see #30.
Note that the sed
expression problem in qtbase/src/mkdef.sh
and qtbase/src/CMakeLists.txt
gets worked-around in the installation instructions by explicitly putting the sed
expression into qtbase/src/mkdef.sh
.
I can't guarantee this will work in general, but I think that's what worked for me on my Win7 VM. I can't get my hands on the VM just now to double check that, but I believe that the other issues have been fixed already.
I've just rechecked the installation on Win7 32bit with: R 3.1.0 RTools 3.1.0.1942 cmake 2.8.11 Qt 5.2.0 with minGW 4.8.0, qmake 3.0 and windres 2.32.2
To be more specific, I have the following environment variables set:
CMAKE=C:\Program Files\CMake 2.8\bin\cmake.exe
QMAKE=C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin
RC_COMPILER=C:\Qt\Qt5.2.0\Tools\mingw48_32\bin\windres.exe
PATH=C:\Qt\Qt5.2.0\Tools\mingw48_32\bin;
C:\Rtools\bin;
C:\Rtools\gcc-4.6.3\bin;
C:\Program Files\R\R-3.1.0\bin;
C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin;
C:\Strawberry\perl\bin;
C:\Strawberry\perl\site\bin;
C:\Strawberry\c\bin;
C:\Program Files\CMake 2.8\bin;
[...other directories...]
Just curious about the status - any news, please? Thanks.
Taking a look at the weird stacktrace below (obtained under the same conditions as above) I'm curious whether the problem could not be related to some g++ problems on the windows platform. Or do you think that the stacktrace could simply be a problem of gdb having hard times to restore the stack frames? Not a demonstration of real problems with the qtbase built there?
Program received signal SIGSEGV, Segmentation fault.
0x61c02c9b in ZN18QRasterPaintEngine11ensureBrushERK6QBrush () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
(gdb) bt
#0 0x61c02c9b in ZN18QRasterPaintEngine11ensureBrushERK6QBrush () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
#1 0x0d0522e8 in ?? ()
#2 0x06096000 in ?? ()
#3 0x0000000d in ?? ()
#4 0x409d0800 in ?? ()
#5 0xafd99701 in ?? ()
#6 0x409cb061 in ?? ()
#7 0x03682001 in ?? ()
#8 0x409cb80d in ?? ()
#9 0x00013601 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
BTW I've tried adding "-ggdb" to "set_target_properties" and/or "set(CMAKE_CXX_FLAGS "-m32 -ggdb")" in src/CMakeLists.txt
, but with no effect.
I apologize for not being able to focus on this. Not sure what could be causing the issue. I'm pretty sure the "corrupt stack" is just an indirect symptom. Need to get at the root cause. Could be compiler issues, could be the event loop, who knows.
I promise to look into this over the holidays.
Thanks. Over the last couple of weeks, I've tried to investigate this issue a little bit deeper by compiling Qt5.2.0 from sources and enriching the sources with some debugs. However, I'm afraid I'm not any closer to a solution.
Basically, the problem I face is caused by QRasterPaintEngine::state
set to NULL when it is expected to be non-NULL. The relevant sources are Src/qtbase/src/gui/painting/qpaintengine_raster_p.h
, Src/qtbase/src/gui/painting/qpaintengine_raster.cpp
, and Src/qtbase/src/gui/painting/qpaintengineex.cpp
.
A representative log looks like this:
QRasterPaintEngine::ensureBrush called by 1:04ae53e8:4084:7ffdf000
this x0a962130
state x0a9716a8
state()->lastBrush x0a9718e8
brush x014058f4
brush.style() == Qt::NoBrush: 0
state()->fillFlags 448
cnt -1163005926
QRasterPaintEngine::ensureBrush called by 1:04ae53e8:4084:7ffdf000
this x0a962130
state x00000000
state()->lastBrush x00000240
brush x0a944ac8
brush.style() == Qt::NoBrush: 0
Program received signal SIGSEGV, Segmentation fault.
0x090ed60e in ZN18QRasterPaintEngine11ensureBrushERK6QBrush () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
Note that in the second call to QRasterPaintEngine::ensureBrush
, the method sees the correct this
, but the state
is invalid - set to NULL.
By printing the QRasterPaintEngine::state
over several runs it is evident that it is set to NULL quite often (by whom? not sure - when I place debugs in methods setting it, these methods don't get called!?!) , mostly (if not only) after the call to QRasterPaintEngine::end
from within QOpenGLTimerQuery
. The state then gets usually reset (by calls to setState
), but sometimes it is not, which causes the SIGSEGV.
As I expected the issue could be caused by multithread-related, I tried to identify individual threads by the "called by" info shown above. It consists of pthread_self()
, QThread::currentThread()
, GetCurrentThreadId()
, and getTIB()
(__asm__("movl %%fs:0x18, %0" : "=r" (pTib) : : )
), but all this seems to prove that only o single thread is active in relation to the issue observed.
The backtrace and thread info relevant to the problem above:
(gdb) bt
#0 0x090ed60e in ZN18QRasterPaintEngine11ensureBrushERK6QBrush () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
#1 0x00000ff4 in ?? ()
#2 0x7ffdf000 in ?? ()
#3 0x04b02c00 in ?? ()
#4 0x6691b8c0 in ZN7QThread18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#5 0x667521f0 in ZN7QThreadD0Ev () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#6 0x66752c70 in ZN7QThread3runEv () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#7 0x668c7b50 in ZN7QObject10timerEventEP11QTimerEvent () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#8 0x668c7b60 in ZN7QObject10childEventEP11QChildEvent () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#9 0x668c7b80 in ZN7QObject11eventFilterEPS_P6QEvent () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#10 0x668c7b90 in ZN7QObject13connectNotifyERK11QMetaMethod () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#11 0x667520c0 in ZN10QSemaphore10tryAcquireEii () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#12 0x66939b00 in ZN14QAbstractState6d_funcEv () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#13 0x6682ed60 in ZN9QIODevice5writeEPKcx () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#14 0x66819480 in ZNK7QBuffer10metaObjectEv () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Core.dll
#15 0x00000000 in ?? ()
(gdb) i thr
Id Target Id Frame
10 Thread 3408.0xba8 0x774c70b4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
9 Thread 3408.0x164 0x774c70b4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
8 Thread 3408.0x424 0x774c70b4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
7 Thread 3408.0xbf8 0x774c70b4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
6 Thread 3408.0x160 0x774c70b4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
5 Thread 3408.0xf64 0x774c70b4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
4 Thread 3408.0xcac 0x774c70b4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
3 Thread 3408.0xa68 0x774c70b4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
2 Thread 3408.0xcd8 0x774c70b4 in ntdll!LdrFindResourceEx_U () from C:\Windows\system32\ntdll.dll
* 1 Thread 3408.0xff4 0x090ed60e in ZN18QRasterPaintEngine11ensureBrushERK6QBrush () from C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Gui.dll
(gdb)
A digest of state
-related code from relevant classes (with code from .cpp put inside declarations):
class QPaintEngine
virtual void updateState(const QPaintEngineState &state) = 0;
void syncState() {
Q_ASSERT(state);
updateState(*state);
if (isExtended()) static_cast<QPaintEngineEx *>(this)->sync();
}
protected:
QPaintEngineState *state;
}
class QPaintEngineEx : public QPaintEngine {
virtual QPainterState *createState(QPainterState *orig) const {
if (!orig) return new QPainterState;
return new QPainterState(orig);
}
virtual void updateState(const QPaintEngineState &state) {
// do nothing...
}
virtual void setState(QPainterState *s) {
QPaintEngine::state = s;
}
inline QPainterState *state() {
return static_cast<QPainterState *>(QPaintEngine::state);
}
inline const QPainterState *state() const {
return static_cast<const QPainterState *>(QPaintEngine::state);
}
virtual void sync() {}
}
class QRasterPaintEngine : public QPaintEngineEx
void setState(QPainterState *s) {
Q_D(QRasterPaintEngine);
QPaintEngineEx::setState(s);
d->rasterBuffer->compositionMode = s->composition_mode;
}
QPainterState *createState(QPainterState *orig) const {
QRasterPaintEngineState *s;
if (!orig) s = new QRasterPaintEngineState();
else s = new QRasterPaintEngineState(*static_cast<QRasterPaintEngineState *>(orig));
return s;
}
inline QRasterPaintEngineState *state() {
return static_cast<QRasterPaintEngineState *>(QPaintEngineEx::state());
}
inline const QRasterPaintEngineState *state() const {
return static_cast<const QRasterPaintEngineState *>(QPaintEngineEx::state());
}
void init() {
Q_D(QRasterPaintEngine);
#ifdef Q_OS_WIN
d->hdc = 0;
#endif
...
}
void updateRasterState() {
QRasterPaintEngineState *s = state();
if (s->dirty & DirtyTransform) updateMatrix(s->matrix);
if (s->dirty & (DirtyPen|DirtyCompositionMode|DirtyOpacity)) {
const QPainter::CompositionMode mode = s->composition_mode;
s->flags.fast_text = (s->penData.type == QSpanData::Solid)
&& s->intOpacity == 256
&& (mode == QPainter::CompositionMode_Source
|| (mode == QPainter::CompositionMode_SourceOver
&& qAlpha(s->penData.solid.color) == 255));
}
s->dirty = 0;
}
inline void ensureRasterState() {
if (state()->dirty) updateRasterState();
}
}
Note that the Q_OS_WIN
-specific code in the classes above does not seem to be relevant to the issue.
Some technical comments I mention mostly for (my) reference:
1) when building qtbase
against Qt5.2.0 built from sources, I ran into a problem of multiple defs from Qt5Network
and undefined refs to QAbstractScrollArea
from Qt5Widgets
:
Linking CXX shared library qtbase.dll
d000383.o:(.idata$2+0x0): multiple definition of `_head_Qt5Network_dll'
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Network.a(d000109.o):(.idata$2+0x0): first defined here
d001048.o:(.idata$7+0x0): multiple definition of `Qt5Network_dll_iname'
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Network.a(d001113.o):(.idata$7+0x0): first defined here
C:/src/qtbase-master141107/qtbase/src/../kdebindings-build/smoke/qt/libsmokeqt.a(x_1.cpp.obj):x_1.cpp:(.text$_ZN19QAbstractScrollArea2trEPKcS1_i[__ZN19QAbstractScrollArea2trEPKcS1_i]+0x20):
undefined reference to `_imp___ZN19QAbstractScrollArea16staticMetaObjectE'
C:/src/qtbase-master141107/qtbase/src/../kdebindings-build/smoke/qt/libsmokeqt.a(x_1.cpp.obj):x_1.cpp:(.text$_ZN19QAbstractScrollArea6trUtf8EPKcS1_i[__ZN19QAbstractScrollArea6trUtf8EPKcS1_i]+0x20):
undefined reference to `_imp___ZN19QAbstractScrollArea16staticMetaObjectE'
c:/qt/qt5.2.0/tools/mingw48_32/bin/../lib/gcc/i686-w64-mingw32/4.8.0/../../../../i686-w64-mingw32/bin/ld.exe:
C:/src/qtbase-master141107/qtbase/src/../kdebindings-build/smoke/qt/libsmokeqt.a(x_1.cpp.obj):
bad reloc address 0x20 in section `.text$_ZN19QAbstractScrollArea6trUtf8EPKcS1_i[__ZN19QAbstractScrollArea6trUtf8EPKcS1_i]'
collect2.exe: error: ld returned 1 exit status
I attempted to solve it by removing the Network
and Qt
modules from CMakeLists.txt
(worked) and adding Qt5Widgets
to CMakeLists.txt
:
if(Qt5Widgets_FOUND)
get_target_property(QtWidgets_location Qt5::Widgets LOCATION)
set(LIB_LOC ${LIB_LOC} ${QtWidgets_location})
endif(Qt5Widgets_FOUND)
this resulted in:
Linking CXX shared library qtbase.dll
d000383.o:(.idata$2+0x0): multiple definition of `_head_Qt5Widgets_dll'
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Widgets.a(d000548.o):(.idata$2+0x0): first defined here
d006156.o:(.idata$7+0x0): multiple definition of `Qt5Widgets_dll_iname'
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Widgets.a(d009354.o):(.idata$7+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
I therefore tried to add C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Widgets.a
to the g++ command line. To determine what the command line was (passing VERBOSE=1
to cmake did not work for me for some reason), I plugged in my own g++ which printed the command line and invoked the original g++:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int i;
for (i=0;i<argc;i++) printf("argv[%d]: %s\n",i,argv[i]);
for (i=0;i<argc;i++) printf("%s ",argv[i]);
printf("\n");
argv[0]=(char*)"g++";
execv("C:\\Qt\\Qt5.2.0\\Tools\\mingw48_32\\bin\\g++.orig.exe",argv);
perror("execv");
return 0;
}
producing
argv[0]: C:\Qt\Qt5.2.0\Tools\mingw48_32\bin\g++.exe
argv[1]: -m32
argv[2]: -shared
argv[3]: qtbase.def
argv[4]: qtbase.def
argv[5]: -shared
argv[6]: -o
argv[7]: qtbase.dll
argv[8]: -Wl,--out-implib,libqtbase.dll.a
argv[9]: -Wl,--major-image-version,0,--minor-image-version,0
argv[10]: -Wl,--whole-archive
argv[11]: CMakeFiles/qtbase.dir/objects.a
argv[12]: -Wl,--no-whole-archive
argv[13]: -LC:/src/qtbase-master141107/qtbase/src/../kdebindings-build/smoke/qt
argv[14]: C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Widgets.a
argv[15]: C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Sql.a
argv[16]: -lsmokeqt
argv[17]: -LC:/PROGRA~1/R/R-31~1.0/bin//i386
argv[18]: -lR
argv[19]: C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/bin/Qt5Widgets.dll
argv[20]: C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/bin/Qt5Sql.dll
argv[21]: C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Gui.a
argv[22]: C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Core.a
argv[23]: -lkernel32
argv[24]: -luser32
argv[25]: -lgdi32
argv[26]: -lwinspool
argv[27]: -lshell32
argv[28]: -lole32
argv[29]: -loleaut32
argv[30]: -luuid
argv[31]: -lcomdlg32
argv[32]: -ladvapi32
Then I was able to link qtbase.dll
manually by removing the libQt5Widgets.a
:
g++.exe -m32 -shared qtbase.def qtbase.def -shared -o qtbase.dll -Wl,--out-implib,libqtbase.dll.a \
-Wl,--major-image-version,0,--minor-image-version,0 -Wl,--whole-archive CMakeFiles/qtbase.dir/objects.a \
-Wl,--no-whole-archive -LC:/src/qtbase-master141107/qtbase/src/../kdebindings-build/smoke/qt \
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Sql.a -lsmokeqt -LC:/PROGRA~1/R/R-31~1.0/bin//i386 -lR \
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/bin/Qt5Widgets.dll C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/bin/Qt5Sql.dll \
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Gui.a C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Core.a \
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 \
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Widgets.a
2) make
in Qt5.2.0 sources failed repeatedly for missing symbols. I ended up with compiling only the parts I could compile easily (namely the GUI module) and replacing the original Qt dll's with the newly compiled versions, in particular by copying Qt5Gui.dll
from C:\Qt\Qt5.2.0\5.2.0\Src\qtbase\lib
to C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin
.
3) When updating qpaintengine_raster_p.h
, note that it is present not only in Qt5.2.0\5.2.0\Src/qtbase/src/gui/painting
, but also in Qt5.2.0\5.2.0\Src\qtbase\include\QtGui\5.2.0\QtGui\private
and Qt5.2.0\5.2.0\mingw48_32\include\QtGui\5.2.0\QtGui\private
.
Thanks for all of your efforts. I think this might just be memory corruption, if it is true that nothing is setting the state to NULL
intentionally.
I've managed to get qtbase to build and load, but running the characterWidget demo is blocking the R console, and none of the characters are drawn (it appears that there is some error invoking the paintEvent override). Have you experienced this?
I usually use Rscript from within gdb and experience a crash while drawing the characters or the grid (i.e. the rectangles around the characters). When running from within the R console directly (wout gdb), I experience later crashes: when drawing characters, or even after all the characters have been drawn, on subsequent drawings (e.g. after asking for bold face characters).
I've just run across Dr. Memory - a multiplatform memory debugger: http://drmemory.org. It seems to work well under 32bit Windows 7. Running the characterWidget demo under Rscript, Dr.Memory reported e.g.:
Error #16: UNADDRESSABLE ACCESS: reading 0x00000300-0x00000304 4 byte(s)
# 0 Qt5Gui.dll!? +0x0 (0x096fd4fe <Qt5Gui.dll+0x2cd4fe>)
# 1 Qt5Gui.dll!? +0x0 (0x095decc2 <Qt5Gui.dll+0x1aecc2>)
# 2 Qt5Gui.dll!? +0x0 (0x095ed9b7 <Qt5Gui.dll+0x1bd9b7>)
# 3 qtbase.dll!__smokeqt::x_QPainter::x_187 [C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/include/QtCore/qrefcount.h:72]
# 4 qtbase.dll!__smokeqt::xcall_QPainter [C:/src/qtbase-master141107/qtbase/src/init.cpp:158]
# 5 qtbase.dll!SmokeMethod::invoke [C:/src/qtbase-master141107/qtbase/src/SmokeMethod.cpp:20]
# 6 qtbase.dll!MethodCall::invokeMethod [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:104]
# 7 qtbase.dll!MethodCall::marshal [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:84]
# 8 qtbase.dll!MethodCall::eval [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:117]
# 9 qtbase.dll!ForeignMethod::invoke [C:/src/qtbase-master141107/qtbase/src/ForeignMethod.cpp:6]
#10 qtbase.dll!SmokeMethod::invoke [C:/src/qtbase-master141107/qtbase/src/SmokeMethod.hpp:78]
#11 qtbase.dll!DynamicBinding::invoke [C:/src/qtbase-master141107/qtbase/src/DynamicBinding.cpp:10]
#12 qtbase.dll!qt_qinvoke [C:/src/qtbase-master141107/qtbase/src/invoke.cpp:17]
#13 R.dll!? +0x0 (0x6c81c612 <R.dll+0x11c612>)
#14 R.dll!? +0x0 (0x6c77ec0a <R.dll+0x7ec0a>)
#15 R.dll!? +0x0 (0x6c77f693 <R.dll+0x7f693>)
#16 R.dll!? +0x0 (0x6c77e9e7 <R.dll+0x7e9e7>)
#17 R.dll!? +0x0 (0x6c782b16 <R.dll+0x82b16>)
#18 R.dll!? +0x0 (0x6c77e777 <R.dll+0x7e777>)
#19 R.dll!? +0x0 (0x6c782b16 <R.dll+0x82b16>)
Note: @0:00:56.628 in thread 3424
Note: instruction: mov 0x00000300(%eax) -> %eax
Would that help?
Thanks, I had installed drmemory and was planning on doing the same thing. Do you think you could build Qt with debugging symbols, so that the stacktrace is more informative?
I have built both the release and debug Qt versions (e.g. .dll and d.dll) . How do I make qtbase to use the debug version, please?
Never done it before, but I think you can pass -DCMAKE_BUILD_TYPE=DEBUG to the cmake command from the Makefile.
Thanks. Adding -DCMAKE_BUILD_TYPE=DEBUG to CMAKE_ARGS in src/Makefile.common and src/Makefile.win resulted in the following error when loading qtbase:
QWidget: Must construct a QApplication before a QWidget
which perhaps (based on google search) signals a mixture of release and debug libraries being used at the same time.
Using ntldd (see https://github.com/LRN/ntldd) I could really spot such a mixture:
ntldd qtbase.dll
Qt5Cored.dll => C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Cored.dll (0x03E50000)
Qt5Guid.dll => C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Guid.dll (0x09E50000)
Qt5Widgetsd.dll => C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Widgetsd.dll (0x09E50000)
libgcc_s_dw2-1.dll => C:\Qt\Qt5.2.0\Tools\mingw48_32\bin\libgcc_s_dw2-1.dll (0x00490000)
KERNEL32.dll => C:\Windows\system32\KERNEL32.dll (0x08830000)
msvcrt.dll => C:\Windows\system32\msvcrt.dll (0x08830000)
libwinpthread-1.dll => C:\Qt\Qt5.2.0\Tools\mingw48_32\bin\libwinpthread-1.dll (0x00250000)
USER32.dll => C:\Windows\system32\USER32.dll (0x089A0000)
libstdc++-6.dll => C:\Qt\Qt5.2.0\Tools\mingw48_32\bin\libstdc++-6.dll (0x08830000)
Qt5Sql.dll => C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Sql.dll (0x00250000)
Qt5Widgets.dll => C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\Qt5Widgets.dll (0x04650000)
R.dll => not found
Can't tell where do the release versions come from. There are both debug and release versions of e.g. Qt5SQL and Qt5Widget in C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin. Note that qtbase.dll seems to be linked against both the debug and release versions of Qt5Widgets.dll for some reason.
The dependency walker tool may offer some clues.
The dependency walker helped by specifying which symbols of one of the problematic libs (Qt5Widgets.dll) gets exposed, e.g._Z13qDrawWinPanelP8QPainterRK5QRectRK8QPalettebPK6QBrush. This symbol appears in libsmokeqt.a - even though I put "set(CMAKE_BUILD_TYPE Debug)" to kdebindings/smoke/qt/CMakeLists.txt (and others CMakeLists.txt in kdebindings).
When building kdebindings, it seems that debug mode is turned on:
Linking CXX static library libsmokeqt.a
[100%] Built target smokeqt
Install the project...
-- Install configuration: "Debug"
Still don't know why qtbase.dll links to release-version Qt libs.
Do you think it is worthy to proceed further (to make use of debug Qt libs)? Would a file/line-enriched stacktrace really that helpful?
If you set VERBOSE=1
in the invocation of make
you can see the actual linker line. Then we can see where the non-debug DLLs are being linked. As far as it being worth it, yes, it would be nice to have debugging symbols if we're going to debug Qt, which seems necessary in this case. It would also help if you pasted your definition of x_QPainter::x_187
, because that is dynamically generated and thus varies across installations. Thanks for your perseverance!
Thanks for the hint. The problem was qtbase.dll linking, in which release versions of Qt5 libs appeared:
g++ -m32 -shared qtbase.def qtbase.def -shared -o qtbase.dll
-Wl,--out-implib,libqtbase.dll.a
-Wl,--major-image-version,0,--minor-image-version,0
-Wl,--whole-archive
CMakeFiles/qtbase.dir/objects.a -Wl,--no-whole-archive
-LC:/src/qtbase-master141107/qtbase/src/../kdebindings-build/smoke/qt
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Widgetsd.a
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Sqld.a
-lsmokeqt
-LC:/PROGRA~1/R/R-31~1.0/bin//i386
-lR
=> C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/bin/Qt5Widgets.dll
=> C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/bin/Qt5Sql.dll
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Guid.a
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Cored.a
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32
-loleaut32 -luuid -lcomdlg32 -ladvapi32
I solved it manually by hacking the linking command, using debug versions of the .a libs:
g++ -m32 -shared qtbase.def qtbase.def -shared -o qtbase.dll
-Wl,--out-implib,libqtbase.dll.a
-Wl,--major-image-version,0,--minor-image-version,0
-Wl,--whole-archive
CMakeFiles/qtbase.dir/objects.a -Wl,--no-whole-archive
-LC:/src/qtbase-master141107/qtbase/src/../kdebindings-build/smoke/qt
-lsmokeqt -LC:/PROGRA~1/R/R-31~1.0/bin//i386 -lR
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Widgetsd.a
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Sqld.a
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Guid.a
C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/lib/libQt5Cored.a -lkernel32 -luser32
-lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32
-ladvapi32
Then, running the characterWidget.R in Rterm under Dr.Memory, I could see the debug info for Qt5Gui.
The relevant problem reported was:
Error #22: UNADDRESSABLE ACCESS: reading 0x00000240-0x00000244 4 byte(s)
# 0 Qt5Guid.dll!QScopedPointer<>::data [../../include/QtCore/qscopedpointer.h:143]
# 1 Qt5Guid.dll!operator==<> [../../include/QtCore/qscopedpointer.h:184]
# 2 Qt5Guid.dll!qbrush_fast_equals [../../include/QtGui/5.2.0/QtGui/private/qpainter_p.h:95]
# 3 Qt5Guid.dll!QRasterPaintEngine::ensureBrush [../../include/QtGui/5.2.0/QtGui/private/qpaintengine_raster_p.h:253]
# 4 Qt5Guid.dll!QRasterPaintEngine::fillRect [painting/qpaintengine_raster.cpp:1831]
# 5 Qt5Guid.dll!QPainter::fillRect [painting/qpainter.cpp:6886]
# 6 qtbase.dll!__smokeqt::x_QPainter::x_187 [C:/src/qtbase-master141107/qtbase/kdebindings-build/smoke/qt/x_11.cpp:3008]
# 7 qtbase.dll!__smokeqt::xcall_QPainter [C:/src/qtbase-master141107/qtbase/kdebindings-build/smoke/qt/x_11.cpp:3732]
# 8 qtbase.dll!SmokeMethod::invoke [C:/src/qtbase-master141107/qtbase/src/SmokeMethod.cpp:20]
# 9 qtbase.dll!MethodCall::invokeMethod [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:104]
#10 qtbase.dll!MethodCall::marshal [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:84]
#11 qtbase.dll!MethodCall::eval [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:117]
#12 qtbase.dll!ForeignMethod::invoke [C:/src/qtbase-master141107/qtbase/src/ForeignMethod.cpp:6]
#13 qtbase.dll!SmokeMethod::invoke [C:/src/qtbase-master141107/qtbase/src/SmokeMethod.hpp:78]
#14 qtbase.dll!DynamicBinding::invoke [C:/src/qtbase-master141107/qtbase/src/DynamicBinding.cpp:10]
#15 qtbase.dll!qt_qinvoke [C:/src/qtbase-master141107/qtbase/src/invoke.cpp:17]
#16 R.dll!? +0x0 (0x6c81c612 <R.dll+0x11c612>)
#17 R.dll!? +0x0 (0x6c77ec0a <R.dll+0x7ec0a>)
#18 R.dll!? +0x0 (0x6c77f693 <R.dll+0x7f693>)
#19 R.dll!? +0x0 (0x6c77e9e7 <R.dll+0x7e9e7>)
Note: @0:01:18.983 in thread 3756
Note: instruction: mov (%eax) -> %eax
Decorating with some code gives:
Error #22: UNADDRESSABLE ACCESS: reading 0x00000240-0x00000244 4 byte(s)
# 0 Qt5Guid.dll!QScopedPointer<>::data [../../include/QtCore/qscopedpointer.h:143]
class QScopedPointer
{
typedef T *QScopedPointer:: *RestrictedBool;
public:
explicit inline QScopedPointer(T *p = 0) : d(p)
{
}
inline T *data() const
{
=> return d;
}
...
protected:
T *d;
# 1 Qt5Guid.dll!operator==<> [../../include/QtCore/qscopedpointer.h:184]
class QScopedPointer
{
...
template <class T, class Cleanup>
inline bool operator==(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs)
{
=> return lhs.data() == rhs.data();
}
# 2 Qt5Guid.dll!qbrush_fast_equals [../../include/QtGui/5.2.0/QtGui/private/qpainter_p.h:95]
=> inline bool qbrush_fast_equals(const QBrush &a, const QBrush &b) { return data_ptr(a) == data_ptr(b); }
note: qbrush.h:
class Q_GUI_EXPORT QBrush
{
public:
...
typedef QScopedPointer<QBrushData, QBrushDataPointerDeleter> DataPtr;
inline DataPtr &data_ptr() { return d; }
};
# 3 Qt5Guid.dll!QRasterPaintEngine::ensureBrush [../../include/QtGui/5.2.0/QtGui/private/qpaintengine_raster_p.h:253]
inline void ensureBrush(const QBrush &brush) {
=> if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags))
updateBrush(brush);
}
# 4 Qt5Guid.dll!QRasterPaintEngine::fillRect [painting/qpaintengine_raster.cpp:1831]
void QRasterPaintEngine::fillRect(const QRectF &r, const QBrush &brush)
{
#ifdef QT_DEBUG_DRAW
qDebug() << "QRasterPaintEngine::fillRecct(): " << r << brush;
#endif
QRasterPaintEngineState *s = state();
=> ensureBrush(brush);
# 5 Qt5Guid.dll!QPainter::fillRect [painting/qpainter.cpp:6886]
void QPainter::fillRect(const QRect &r, const QBrush &brush)
{
Q_D(QPainter);
if (!d->engine)
return;
if (d->extended) {
const QGradient *g = brush.gradient();
if (!g || g->coordinateMode() == QGradient::LogicalMode) {
=> d->extended->fillRect(r, brush);
return;
}
}
# 6 qtbase.dll!__smokeqt::x_QPainter::x_187 [C:/src/qtbase-master141107/qtbase/kdebindings-build/smoke/qt/x_11.cpp:3008]
void x_187(Smoke::Stack x) {
// void fillRect(const QRect&, const QBrush&)
=> this->QPainter::fillRect(*(const QRect*)x[1].s_class,*(const QBrush*)x[2].s_class);
(void)x; // noop (for compiler warning)
}
# 7 qtbase.dll!__smokeqt::xcall_QPainter [C:/src/qtbase-master141107/qtbase/kdebindings-build/smoke/qt/x_11.cpp:3732]
=> case 187: xself->x_187(args); break;
# 8 qtbase.dll!SmokeMethod::invoke [C:/src/qtbase-master141107/qtbase/src/SmokeMethod.cpp:20]
# 9 qtbase.dll!MethodCall::invokeMethod [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:104]
#10 qtbase.dll!MethodCall::marshal [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:84]
#11 qtbase.dll!MethodCall::eval [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:117]
#12 qtbase.dll!ForeignMethod::invoke [C:/src/qtbase-master141107/qtbase/src/ForeignMethod.cpp:6]
#13 qtbase.dll!SmokeMethod::invoke [C:/src/qtbase-master141107/qtbase/src/SmokeMethod.hpp:78]
#14 qtbase.dll!DynamicBinding::invoke [C:/src/qtbase-master141107/qtbase/src/DynamicBinding.cpp:10]
#15 qtbase.dll!qt_qinvoke [C:/src/qtbase-master141107/qtbase/src/invoke.cpp:17]
#16 R.dll!? +0x0 (0x6c81c612 <R.dll+0x11c612>)
#17 R.dll!? +0x0 (0x6c77ec0a <R.dll+0x7ec0a>)
#18 R.dll!? +0x0 (0x6c77f693 <R.dll+0x7f693>)
#19 R.dll!? +0x0 (0x6c77e9e7 <R.dll+0x7e9e7>)
Note: @0:01:18.983 in thread 3756
Note: instruction: mov (%eax) -> %eax
I put the full Dr.Memory log drmem_results.txt
as well as the generated x_11.cpp
file here: https://github.com/tsieger/qtbase/tree/logs/logs/150126.
I also tried enabling QT_DEBUG_DRAW. Then, the characterWidget.R
demo
stalled before the characters got painted. The relevant debug is here:
https://github.com/tsieger/qtbase/blob/logs/logs/150126/log_QT_DEBUG_DRAW.txt, but I could not spot anything suspicious IMHO.
Next, I ran the demo with QT_DEBUG_DRAW enabled under Dr.Memory. Besides some unaddressable "system" write accesses that could be seen even before, I could see some unaddressable read accesses caused perhaps by the debugs enabled, e.g.:
Error #155: UNADDRESSABLE ACCESS of freed memory: reading 0x028be629-0x028be62a 1 byte(s)
# 0 R.dll!? +0x0 (0x6c913144 <R.dll+0x213144>)
# 1 R.dll!? +0x0 (0x6c915120 <R.dll+0x215120>)
# 2 R.dll!? +0x0 (0x6c7b3b44 <R.dll+0xb3b44>)
# 3 R.dll!? +0x0 (0x6c72feca <R.dll+0x2feca>)
# 4 R.dll!? +0x0 (0x6c72ff27 <R.dll+0x2ff27>)
# 5 Qt5Cored.dll!qt_message_print [global/qlogging.cpp:948]
# 6 Qt5Cored.dll!qt_message_output [global/qlogging.cpp:991]
# 7 Qt5Guid.dll!QDebug::~QDebug [../../include/QtCore/qdebug.h:87]
# 8 Qt5Guid.dll!QRasterPaintEngine::end [painting/qpaintengine_raster.cpp:562]
# 9 Qt5Guid.dll!QPainter::end [painting/qpainter.cpp:1885]
#10 Qt5Guid.dll!QImageTextureGlyphCache::fillTexture [painting/qtextureglyphcache.cpp:353]
#11 Qt5Guid.dll!QTextureGlyphCache::fillInPendingGlyphs [painting/qtextureglyphcache.cpp:281]
#12 Qt5Guid.dll!QRasterPaintEngine::drawCachedGlyphs [painting/qpaintengine_raster.cpp:2855]
#13 Qt5Guid.dll!QRasterPaintEngine::drawTextItem [painting/qpaintengine_raster.cpp:3108]
#14 Qt5Guid.dll!QPainterPrivate::drawTextItem [painting/qpainter.cpp:6459]
#15 Qt5Guid.dll!QTextLine::draw [text/qtextlayout.cpp:2522]
#16 Qt5Guid.dll!QTextLayout::draw [text/qtextlayout.cpp:1197]
#17 Qt5Widgetsd.dll!QWidgetLineControl::draw [widgets/qwidgetlinecontrol.cpp:616]
#18 Qt5Widgetsd.dll!QLineEdit::paintEvent [widgets/qlineedit.cpp:1981]
#19 Qt5Widgetsd.dll!QWidget::event [kernel/qwidget.cpp:8102]
Note: @0:01:41.884 in thread 2248
Note: 0x028be629-0x028be62a overlaps memory 0x028be618-0x028be698 that was freed here:
Note: # 0 replace_free [d:\drmemory_package\common\alloc_replace.c:2503]
Note: # 1 Qt5Cored.dll!QArrayData::deallocate [tools/qarraydata.cpp:125]
Note: # 2 qtbase.dll!QTypedArrayData<>::deallocate [C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/include/QtCore/qarraydata.h:230]
Note: # 3 qtbase.dll!QByteArray::~QByteArray [C:/Qt/Qt5.2.0/5.2.0/Src/qtbase/include/QtCore/qbytearray.h:409]
Note: # 4 qtbase.dll!R_Qt_msgHandler [C:/src/qtbase-master141107/qtbase/src/EventLoop.cpp:139]
Note: # 5 Qt5Cored.dll!qt_message_print [global/qlogging.cpp:948]
Note: instruction: cmp (%esi,%eax,1) $0x00
(perhaps not harmful?).
However, errors 241+ seem to show huge memory corruption, e.g.:
Error #242: UNADDRESSABLE ACCESS of freed memory: writing 0x027af02c-0x027af030 4 byte(s)
# 0 Qt5Guid.dll!QPainterPrivate::drawTextItem [painting/qpainter.cpp:6466]
# 1 Qt5Guid.dll!QTextLine::draw [text/qtextlayout.cpp:2522]
# 2 Qt5Guid.dll!QTextLayout::draw [text/qtextlayout.cpp:1197]
# 3 Qt5Guid.dll!QTextDocumentLayoutPrivate::drawBlock [text/qtextdocumentlayout.cpp:1338]
# 4 Qt5Guid.dll!QTextDocumentLayoutPrivate::drawFlow [text/qtextdocumentlayout.cpp:1236]
# 5 Qt5Guid.dll!QTextDocumentLayoutPrivate::drawFrame [text/qtextdocumentlayout.cpp:1087]
# 6 Qt5Guid.dll!QTextDocumentLayout::draw [text/qtextdocumentlayout.cpp:2846]
# 7 Qt5Widgetsd.dll!QWidgetTextControl::drawContents [widgets/qwidgettextcontrol.cpp:3099]
# 8 Qt5Widgetsd.dll!QLabel::paintEvent [widgets/qlabel.cpp:1045]
# 9 Qt5Widgetsd.dll!QTipLabel::paintEvent [kernel/qtooltip.cpp:231]
#10 Qt5Widgetsd.dll!QWidget::event [kernel/qwidget.cpp:8102]
#11 Qt5Widgetsd.dll!QFrame::event [widgets/qframe.cpp:534]
#12 Qt5Widgetsd.dll!QLabel::event [widgets/qlabel.cpp:988]
#13 Qt5Widgetsd.dll!QApplicationPrivate::notify_helper [kernel/qapplication.cpp:3467]
#14 Qt5Widgetsd.dll!QApplication::notify [kernel/qapplication.cpp:3432]
#15 Qt5Cored.dll!QCoreApplication::notifyInternal [kernel/qcoreapplication.cpp:878]
#16 Qt5Widgetsd.dll!QCoreApplication::sendSpontaneousEvent [../../include/QtCore/qcoreapplication.h:235]
#17 Qt5Widgetsd.dll!QWidgetPrivate::drawWidget [kernel/qwidget.cpp:5142]
#18 Qt5Widgetsd.dll!QWidgetPrivate::render [kernel/qwidget.cpp:5274]
#19 Qt5Widgetsd.dll!QWidget::render [kernel/qwidget.cpp:4675]
Note: @0:18:18.305 in thread 2248
Note: next higher malloc: 0x027af350-0x027af378
Note: prev lower malloc: 0x027ae760-0x027aeb64
Note: 0x027af02c-0x027af030 overlaps memory 0x027aef88-0x027af154 that was freed here:
Note: # 0 replace_free [d:\drmemory_package\common\alloc_replace.c:2503]
Note: # 1 Qt5Guid.dll!QTextEngine::LayoutData::~LayoutData [text/qtextengine.cpp:2266]
Note: # 2 Qt5Guid.dll!QTextEngine::~QTextEngine [text/qtextengine.cpp:1355]
Note: # 3 Qt5Guid.dll!QTextLayout::~QTextLayout [text/qtextlayout.cpp:366]
Note: # 4 Qt5Guid.dll!QTextBlockData::free [text/qtextdocument_p.h:109]
Note: # 5 Qt5Guid.dll!QFragmentMap<>::~QFragmentMap [../../include/QtGui/5.2.0/QtGui/private/qfragmentmap_p.h:807]
Note: instruction: mov %eax -> (%edx)
The full log can be found at https://github.com/tsieger/qtbase/blob/logs/logs/150126/log_QT_DEBUG_DRAW_drmem.txt. A log with longer stack frames is here: https://github.com/tsieger/qtbase/blob/logs/logs/150126/log_QT_DEBUG_DRAW_drmem_more_frames.txt.
Wow, thanks for all of that. It does look like there is corruption of the QPainter
object. Perhaps you could try turning on debugging of the SmokeObject
memory management (by uncommenting the MEM_DEBUG
define in SmokeObject.cpp
. Maybe something is being freed prematurely.
When turned SmokeObject
debugs on, it really looks like the problem in Qt might be related to SmokeObject
:
0x29f6540: destructing
Debug: 0x297e330: invalidating internal table 0x91d28e8
Debug: 0x2852a18: invalidating sexp 0x91d2728 (QSize)
Debug: 0x2852a18: invoking destructor on 0x289b018
Debug: 0x2852a18: destructing
Debug: 0x297e330: invalidating internal table 0x91d3c78
Debug: 0x297e330: invalidating internal table 0x91d39bc
Debug: 0x28791b8: invalidating sexp 0x91d38a4 (QSize)
Debug: 0x28791b8: invoking destructor on 0x27daf38
Debug: 0x28791b8: destructing
Debug: 0x297e330: invalidating internal table 0x91d3e98
Debug: 0x286b128: invalidating sexp 0x91d4b1c (QSize)
Debug: 0x286b128: invoking destructor on 0x2894288
Debug: 0x286b128: destructing
Debug: 0x297e330: invalidating internal table 0x91d4ff8
Debug: 0x297e330: invalidating internal table 0x91d4dc8
Debug: 0x294e3a8: created for 0x2892908 (QBrush)
Debug: 0x294e3a8: created sexp 0x910a55c
~~Dr.M~~
~~Dr.M~~ Error #158: UNADDRESSABLE ACCESS: reading 0x00000240-0x00000244 4 byte(s)
~~Dr.M~~ # 0 Qt5Guid.dll!QScopedPointer<>::data [../../include/QtCore/qscopedpointer.h:143]
~~Dr.M~~ # 1 Qt5Guid.dll!operator==<> [../../include/QtCore/qscopedpointer.h:184]
~~Dr.M~~ # 2 Qt5Guid.dll!qbrush_fast_equals [../../include/QtGui/5.2.0/QtGui/private/qpainter_p.h:95]
~~Dr.M~~ # 3 Qt5Guid.dll!QRasterPaintEngine::ensureBrush [../../include/QtGui/5.2.0/QtGui/private/qpaintengine_raster_p.h:253]
~~Dr.M~~ # 4 Qt5Guid.dll!QRasterPaintEngine::fillRect [painting/qpaintengine_raster.cpp:1831]
~~Dr.M~~ # 5 Qt5Guid.dll!QPainter::fillRect [painting/qpainter.cpp:6886]
~~Dr.M~~ # 6 qtbase.dll!__smokeqt::x_QPainter::x_187 [C:/src/qtbase-master141107/qtbase/kdebindings-build/smoke/qt/x_11.cpp:3008]
~~Dr.M~~ # 7 qtbase.dll!__smokeqt::xcall_QPainter [C:/src/qtbase-master141107/qtbase/kdebindings-build/smoke/qt/x_11.cpp:3732]
~~Dr.M~~ # 8 qtbase.dll!SmokeMethod::invoke [C:/src/qtbase-master141107/qtbase/src/SmokeMethod.cpp:20]
~~Dr.M~~ # 9 qtbase.dll!MethodCall::invokeMethod [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:104]
~~Dr.M~~ #10 qtbase.dll!MethodCall::marshal [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:84]
~~Dr.M~~ #11 qtbase.dll!MethodCall::eval [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:117]
~~Dr.M~~ #12 qtbase.dll!ForeignMethod::invoke [C:/src/qtbase-master141107/qtbase/src/ForeignMethod.cpp:6]
~~Dr.M~~ #13 qtbase.dll!SmokeMethod::invoke [C:/src/qtbase-master141107/qtbase/src/SmokeMethod.hpp:78]
~~Dr.M~~ #14 qtbase.dll!DynamicBinding::invoke [C:/src/qtbase-master141107/qtbase/src/DynamicBinding.cpp:10]
~~Dr.M~~ #15 qtbase.dll!qt_qinvoke [C:/src/qtbase-master141107/qtbase/src/invoke.cpp:17]
~~Dr.M~~ #16 R.dll!? +0x0 (0x6c81c612 <R.dll+0x11c612>)
~~Dr.M~~ #17 R.dll!? +0x0 (0x6c77ec0a <R.dll+0x7ec0a>)
~~Dr.M~~ #18 R.dll!? +0x0 (0x6c77f693 <R.dll+0x7f693>)
~~Dr.M~~ #19 R.dll!? +0x0 (0x6c77e9e7 <R.dll+0x7e9e7>)
~~Dr.M~~ Note: @0:02:26.687 in thread 1824
~~Dr.M~~ Note: instruction: mov (%eax) -> %eax
Full log: https://github.com/tsieger/qtbase/blob/logs/logs/150126/log_smoke_drmem.txt
I'm not sure I spot anything wrong with SmokeObject
, but maybe you see something I'm missing. I checked in a possible fix for the memory violations during logging. Please let me know if it improves things.
You are right - there is no clear link between the SmokeObject
and the problem (e.g. in terms of lost pointers appearing both in SmokeObject
and Dr.Memory debugs), the only (false) coincidence was that the problem appeared "immediately" after ops in SmokeObject
took place (a poor link, sorry for that).
BTW the fix for the memory violations during logging worked. Thanks.
I also tried to disable some deallocations in SmokeObject
in hope to postpone/avoid the memory problems. This did not help at all.
I noticed that the problem arises (not sure if always) when processing an event recursively:
...
Debug: SmokeObject::fromPtr(prt 0x26ee5b0, class 0x26ec7a0, allocated 0, copy 0
Debug: SmokeObject::fromPtr(prt 0x26ee5b0, class 0x26a8a00, allocated 0, copy 0
Debug: SmokeObject::fromPtr(prt 0x26ee5b0, class 0x26a8a00, allocated 0, copy 0
Debug: SmokeObject::fromPtr(prt 0x26ee5b0, class 0x26ec7a0, allocated 0, copy 0
Debug: SmokeObject::fromPtr(prt 0x26ee5b0, class 0x26a8a00, allocated 0, copy 0
Debug: SmokeObject::fromPtr(prt 0x26e66c0, class 0x26a8a00, allocated 0, copy 0
Debug: SmokeObject::fromPtr(prt 0x26d93b0, class 0x26a8a00, allocated 0, copy 0
Debug: SmokeObject::fromPtr(prt 0x26ee5b0, class 0x26ec7a0, allocated 0, copy 0
Debug: SmokeObject::fromPtr(prt 0x26d93b0, class 0x26a8a00, allocated 0, copy 0
~~Dr.M~~
~~Dr.M~~ Error #28: UNADDRESSABLE ACCESS: reading 0x0000023c-0x00000240 4 byte(s)
~~Dr.M~~ # 0 Qt5Guid.dll!QRasterPaintEngine::penChanged [painting/qpaintengine_raster.cpp:751]
~~Dr.M~~ # 1 Qt5Guid.dll!QPainter::initFrom [painting/qpainter.cpp:1544]
~~Dr.M~~ # 2 Qt5Guid.dll!QPainter::begin [painting/qpainter.cpp:1820]
~~Dr.M~~ # 3 Qt5Guid.dll!QPainter::QPainter [painting/qpainter.cpp:1467]
~~Dr.M~~ # 4 Qt5Widgetsd.dll!QMainWindow::event [widgets/qmainwindow.cpp:1361]
~~Dr.M~~ # 5 qtbase.dll!__smokeqt::x_QMainWindow::event [C:/src/qtbase-master141107/qtbase/kdebindings-build/smoke/qt/x_9.cpp:10868]
~~Dr.M~~ # 6 Qt5Widgetsd.dll!QApplicationPrivate::notify_helper [kernel/qapplication.cpp:3467]
~~Dr.M~~ # 7 Qt5Widgetsd.dll!QApplication::notify [kernel/qapplication.cpp:3432]
~~Dr.M~~ # 8 Qt5Cored.dll!QCoreApplication::notifyInternal [kernel/qcoreapplication.cpp:878]
~~Dr.M~~ # 9 Qt5Widgetsd.dll!QCoreApplication::sendSpontaneousEvent [../../include/QtCore/qcoreapplication.h:235]
~~Dr.M~~ #10 Qt5Widgetsd.dll!QWidgetPrivate::drawWidget [kernel/qwidget.cpp:5142]
~~Dr.M~~ #11 Qt5Widgetsd.dll!QWidgetBackingStore::sync [kernel/qwidgetbackingstore.cpp:1090]
~~Dr.M~~ #12 Qt5Widgetsd.dll!QWidgetPrivate::syncBackingStore [kernel/qwidget.cpp:1686]
~~Dr.M~~ #13 Qt5Widgetsd.dll!QWidget::event [kernel/qwidget.cpp:8240]
~~Dr.M~~ #14 Qt5Widgetsd.dll!QMainWindow::event [widgets/qmainwindow.cpp:1487]
~~Dr.M~~ #15 qtbase.dll!__smokeqt::x_QMainWindow::event [C:/src/qtbase-master141107/qtbase/kdebindings-build/smoke/qt/x_9.cpp:10868]
~~Dr.M~~ #16 Qt5Widgetsd.dll!QApplicationPrivate::notify_helper [kernel/qapplication.cpp:3467]
~~Dr.M~~ #17 Qt5Widgetsd.dll!QApplication::notify [kernel/qapplication.cpp:3432]
~~Dr.M~~ #18 Qt5Cored.dll!QCoreApplication::notifyInternal [kernel/qcoreapplication.cpp:878]
~~Dr.M~~ #19 Qt5Cored.dll!QCoreApplication::sendEvent [../../include/QtCore/qcoreapplication.h:232]
~~Dr.M~~ #20 Qt5Cored.dll!QCoreApplicationPrivate::sendPostedEvents [kernel/qcoreapplication.cpp:1482]
~~Dr.M~~ #21 Qt5Cored.dll!QCoreApplication::sendPostedEvents [kernel/qcoreapplication.cpp:1340]
~~Dr.M~~ #22 qwindowsd.dll!QWindowsGuiEventDispatcher::sendPostedEvents [C:\Qt\Qt5.2.0\5.2.0\Src\qtbase\src\plugins\platforms\windows/qwindowsguieventdispatcher.cpp:88]
~~Dr.M~~ #23 Qt5Cored.dll!qt_internal_proc@16 [kernel/qeventdispatcher_win.cpp:421]
~~Dr.M~~ #24 USER32.dll!gapfnScSendMessage +0x1ce (0x75d2c4e7 <USER32.dll+0x1c4e7>)
~~Dr.M~~ #25 USER32.dll!gapfnScSendMessage +0x2ce (0x75d2c5e7 <USER32.dll+0x1c5e7>)
~~Dr.M~~ #26 USER32.dll!gapfnScSendMessage +0x900 (0x75d2cc19 <USER32.dll+0x1cc19>)
~~Dr.M~~ #27 USER32.dll!DispatchMessageA +0xe (0x75d22e41 <USER32.dll+0x12e41>)
~~Dr.M~~ #28 Rgraphapp.dll!GA_doevent [/data/gannet/ripley/Sources/mingw-test3/src/mingw-w64/stable/v2.x/mingw-w64-crt/crt/crt.dll.c:166]
~~Dr.M~~ #29 R.dll!? +0x0 (0x6c71e16a <R.dll+0x1e16a>)
~~Dr.M~~ Note: @0:02:48.043 in thread 3584
~~Dr.M~~ Note: instruction: mov 0x0000023c(%eax) -> %eax
(Full log at https://github.com/tsieger/qtbase/blob/logs/logs/150126/log_smoke_drmem-reentrancy.txt)
Maybe, some code involved is not reentrant?
It seems that most/all problems are caused by code like state()->doSomething()
, where state()
returns NULL for some reason.
Maybe, the internal state gets lost, perhaps on recursive calls?
BTW it seems that some other people had problems similar to ours: https://bugreports.qt.io/browse/QTBUG-22102, and http://www.freecadweb.org/tracker/view.php?id=640&nbn=10. The former says that their problem does not arise when switching to the gtk style. Would a style switch be applicable to qtbase? In the latter bug, the author mentions the "QWidget::repaint: Recursive repaint detected" problem I'm familiar with - it appears on Mac sometimes, usually just after qtbase/qtpaint/cranvas installation, when loading and running some qtbase/qtpaint/cranvas code. (The remedy there is to restart R just after installation.)
Also, I tried to make the state()->something()
Qt code (in Src/qtbase/src/gui/painting/qpaintengine_raster.cpp
and
Src/qtbase/src/gui/painting/qpaintengine_raster.h
) more robust (by silently returning when state()==NULL). This seemed to help a little bit in the CharacterWidget demo: even though the character grid was not drawn (maybe, because the code to draw it was omitted due to NULL state()?), I could see the on-fly characters (those drawn inside the R mouseMoveEvent
handler). However, the demo crashed after a while as well, and this crash was left unnoticed by Dr.Memory.
Thanks for this, again. It's interesting that my change fixed the logging issue. It seems very easy to make mistakes with some of these "smart" pointers; who knows where else things are going wrong. Now I am concerned about all of the stack imbalance errors in that log. Did you change something in the code for debugging? If not, then we will need to figure those out.
I also notied that Qt 5.3.0 introduced a Direct2D-based paint engine for Windows. The current crash (and the one cited in 4-year-old, unfixed issue 22102) is in the raster paint engine... so it might be a workaround.
Regarding the stack inbalances - that's the result of my "deallocation-disabling" hack to SmokeObject
, don't worry about that ;-).
I tested qtbase with Qt 5.4.0 some time ago and it did not work. However, I don't know if the Direct2D engine got used, or even if it is available on my Win7 running in a vmware player. (I don't have much Windows graphics experience.) Do you think it could be made working easily?
I think we should at least be using the latest stable version of Qt for this testing. Do you think you could upgrade? As far as enabling the Direct2D backend, there is no documentation, but I think you can set QT_GRAPHICSSYSTEM=direct2d
as an environment variable.
Having QT_GRAPHICSSYSTEM=direct2d
set, the characterWidget demo still crashes on Qt5.4.0 (albeit after a while, not that soon as on Qt5.2.0), but I don't know if the Direct 2D engine gets used or not.
You would see it in the stack trace. Let's remember that Windows has never been very stable, thanks to the competing event loop problems.
I can't see any Direct2D engine in the stacktrace. The problem then seems to be the very same as for Qt4.2.0 (touching NULL state() on recursive repaint):
Error #7: UNADDRESSABLE ACCESS: reading 0x00000240-0x00000244 4 byte(s)
# 0 Qt5Gui.dll!? +0x0 (0x0a4edb40 <Qt5Gui.dll+0x1cdb40>)
# 1 Qt5Gui.dll!? +0x0 (0x0a4fcb72 <Qt5Gui.dll+0x1dcb72>)
# 2 qtbase.dll!__smokeqt::x_QPainter::x_187 [C:/Qt/Qt5.4.0/5.4/mingw491_32/include/QtCore/qrefcount.h:68]
# 3 qtbase.dll!__smokeqt::xcall_QPainter [C:/src/qtbase-master141107/qtbase/src/init.cpp:158]
# 4 qtbase.dll!SmokeMethod::invoke [C:/src/qtbase-master141107/qtbase/src/SmokeMethod.cpp:20]
# 5 qtbase.dll!MethodCall::invokeMethod [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:104]
# 6 qtbase.dll!MethodCall::marshal [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:84]
# 7 qtbase.dll!MethodCall::eval [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:117]
# 8 qtbase.dll!ForeignMethod::invoke [C:/src/qtbase-master141107/qtbase/src/ForeignMethod.cpp:6]
# 9 qtbase.dll!SmokeMethod::invoke [C:/src/qtbase-master141107/qtbase/src/SmokeMethod.hpp:78]
#10 qtbase.dll!DynamicBinding::invoke [C:/src/qtbase-master141107/qtbase/src/DynamicBinding.cpp:10]
#11 qtbase.dll!qt_qinvoke [C:/src/qtbase-master141107/qtbase/src/invoke.cpp:69]
#12 R.dll!? +0x0 (0x6c81c612 <R.dll+0x11c612>)
#13 R.dll!? +0x0 (0x6c77ec0a <R.dll+0x7ec0a>)
#14 R.dll!? +0x0 (0x6c77f693 <R.dll+0x7f693>)
#15 R.dll!? +0x0 (0x6c77e9e7 <R.dll+0x7e9e7>)
#16 R.dll!? +0x0 (0x6c782b16 <R.dll+0x82b16>)
#17 R.dll!? +0x0 (0x6c77e777 <R.dll+0x7e777>)
#18 R.dll!? +0x0 (0x6c782b16 <R.dll+0x82b16>)
#19 R.dll!? +0x0 (0x6c77e777 <R.dll+0x7e777>)
#20 R.dll!? +0x0 (0x6c77f693 <R.dll+0x7f693>)
#21 R.dll!? +0x0 (0x6c77e9e7 <R.dll+0x7e9e7>)
#22 R.dll!? +0x0 (0x6c782b16 <R.dll+0x82b16>)
#23 R.dll!? +0x0 (0x6c77e777 <R.dll+0x7e777>)
#24 R.dll!? +0x0 (0x6c7884b0 <R.dll+0x884b0>)
#25 R.dll!? +0x0 (0x6c789129 <R.dll+0x89129>)
#26 qtbase.dll!MethodCall::invokeMethod [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:97]
#27 qtbase.dll!MethodCall::marshal [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:84]
#28 qtbase.dll!MethodCall::eval [C:/src/qtbase-master141107/qtbase/src/MethodCall.cpp:117]
#29 qtbase.dll!RMethod::invoke [C:/src/qtbase-master141107/qtbase/src/RMethod.cpp:37]
#30 qtbase.dll!DynamicBinding::invoke [C:/src/qtbase-master141107/qtbase/src/DynamicBinding.cpp:21]
#31 qtbase.dll!RSmokeBinding::callMethod [C:/src/qtbase-master141107/qtbase/src/RSmokeBinding.cpp:81]
#32 qtbase.dll!__smokeqt::x_QWidget::paintEvent [C:/Qt/Qt5.4.0/5.4/mingw491_32/include/QtCore/qrefcount.h:68]
#33 Qt5Widgets.dll!? +0x0 (0x61e0ba10 <Qt5Widgets.dll+0x4ba10>)
#34 qtbase.dll!__smokeqt::x_QWidget::event [C:/Qt/Qt5.4.0/5.4/mingw491_32/include/QtCore/qrefcount.h:68]
#35 Qt5Widgets.dll!? +0x0 (0x61dcaf0a <Qt5Widgets.dll+0xaf0a>)
#36 Qt5Widgets.dll!? +0x0 (0x61dcff77 <Qt5Widgets.dll+0xff77>)
#37 Qt5Core.dll!? +0x0 (0x68a444eb <Qt5Core.dll+0x1c44eb>)
#38 Qt5Widgets.dll!? +0x0 (0x61e0479f <Qt5Widgets.dll+0x4479f>)
#39 Qt5Widgets.dll!? +0x0 (0x61e04bde <Qt5Widgets.dll+0x44bde>)
#40 Qt5Widgets.dll!? +0x0 (0x61e05b18 <Qt5Widgets.dll+0x45b18>)
#41 Qt5Widgets.dll!? +0x0 (0x61e0494c <Qt5Widgets.dll+0x4494c>)
#42 Qt5Widgets.dll!? +0x0 (0x61e05b18 <Qt5Widgets.dll+0x45b18>)
#43 Qt5Widgets.dll!? +0x0 (0x61e0598c <Qt5Widgets.dll+0x4598c>)
#44 Qt5Widgets.dll!? +0x0 (0x61e0494c <Qt5Widgets.dll+0x4494c>)
#45 Qt5Widgets.dll!? +0x0 (0x61e05b18 <Qt5Widgets.dll+0x45b18>)
#46 Qt5Widgets.dll!? +0x0 (0x61e0598c <Qt5Widgets.dll+0x4598c>)
#47 Qt5Widgets.dll!? +0x0 (0x61e0598c <Qt5Widgets.dll+0x4598c>)
#48 Qt5Widgets.dll!? +0x0 (0x61e0494c <Qt5Widgets.dll+0x4494c>)
#49 Qt5Widgets.dll!? +0x0 (0x61e05b18 <Qt5Widgets.dll+0x45b18>)
Note: @0:02:10.307 in thread 2704
Note: instruction: mov 0x00000240 -> %eax
Well, we can't know whether it uses the raster engine or not, because there are no debugging symbols in Qt. That might be a lot of effort to rebuild Qt though.
I have hit this in Qt5.15.2.
It happens when a widget repainting causes another paint event. In our case, during a paint event a widget was querying a color value using a scripting command, the scripting engine ran an event loop and scripting command were being echoed in a widget, resulting in a recursive painting.
At the very least, there should be an easy way i the paint engine (QRasterPaintEngine for example) to detect recursive begin/end.
R crashes running some qtbase demos.
E.g. running the
characterWidget
demo results in:The
sliders
demo results in:(Can't get stack trace in this case.)
Some other demos (
groupBox
,addressBook
,widget
) seem to work correctly.Testing on: Windows 7 SP1 32bit R 3.1.0 Qt 4.8.6 qtbase branch qt4