ggobi / qtbase

Dynamic bindings from R to the Qt library
20 stars 7 forks source link

qtbase crash on Windows #28

Open tsieger opened 10 years ago

tsieger commented 10 years ago

R crashes running some qtbase demos.

E.g. running the characterWidget demo results in:

> library(qtbase)
>  source('/src/qtbase-qt4-build-cleaned-test/qtbase/demo/characterWidget.R')
Program received signal SIGSEGV, Segmentation fault.
0x677536ca in ZN14QWidgetPrivate12showChildrenEb () from C:\Qt\4.8.6\bin\QtGui4.dll
(gdb) bt
#0  0x677536ca in ZN14QWidgetPrivate12showChildrenEb () from C:\Qt\4.8.6\bin\QtGui4.dll
#1  0x677537e3 in ZN14QWidgetPrivate11show_helperEv () from C:\Qt\4.8.6\bin\QtGui4.dll
#2  0x67755868 in ZN7QWidget10setVisibleEb () from C:\Qt\4.8.6\bin\QtGui4.dll
#3  0x06d67b37 in __smokeqt::x_QWidget::setVisible(bool) () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#4  0x677536fc in ZN14QWidgetPrivate12showChildrenEb () from C:\Qt\4.8.6\bin\QtGui4.dll
#5  0x677537e3 in ZN14QWidgetPrivate11show_helperEv () from C:\Qt\4.8.6\bin\QtGui4.dll
#6  0x67755868 in ZN7QWidget10setVisibleEb () from C:\Qt\4.8.6\bin\QtGui4.dll
#7  0x06b42d87 in __smokeqt::x_QMainWindow::setVisible(bool) () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#8  0x06a770c1 in QWidget::show() () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#9  0x06d6b063 in __smokeqt::x_QWidget::x_165(Smoke::StackItem*) () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#10 0x069e6676 in __smokeqt::xcall_QWidget(short, void*, Smoke::StackItem*) () from C:\Program Files\R\R-3.1.0\library\qtbase\libs\i386\qtbase.dll
#11 0x0690e6bc in SmokeMethod::invoke (this=0xb175460, obj=0x49caa28, stack=0xb1716f0) at C:/src/qtbase-qt4/qtbase/src/SmokeMethod.cpp:20
#12 0x0691043b in MethodCall::invokeMethod (this=0x140c2e4) at C:/src/qtbase-qt4/qtbase/src/MethodCall.cpp:104
#13 0x06910356 in MethodCall::marshal (this=0x140c2e4) at C:/src/qtbase-qt4/qtbase/src/MethodCall.cpp:84
#14 0x069104dc in MethodCall::eval (this=0x140c2e4) at C:/src/qtbase-qt4/qtbase/src/MethodCall.cpp:117
#15 0x0690e559 in ForeignMethod::invoke (this=0xb175460, obj=0x6898298, args=0x67842a0) at C:/src/qtbase-qt4/qtbase/src/ForeignMethod.cpp:6
#16 0x06a1ed40 in SmokeMethod::invoke (this=0xb175460, obj=0x6898298, args=0x67842a0) at C:/src/qtbase-qt4/qtbase/src/SmokeMethod.hpp:78
#17 0x0690f79b in DynamicBinding::invoke (this=0x140c3c0, obj=0x6898298, args=0x67842a0) at C:/src/qtbase-qt4/qtbase/src/DynamicBinding.cpp:10
#18 0x0690a021 in qt_qinvoke (self=0x6898298, method=0x95fc9d0, super=0x95d3200, args=0x67842a0) at C:/src/qtbase-qt4/qtbase/src/invoke.cpp:17
#19 0x6c81c612 in Runzip () from C:\Program Files\R\R-3.1.0\bin\i386\R.dll
#20 0x0678b9c8 in ?? ()
#21 0x021a24a0 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

The sliders demo results in:

>  source('/src/qtbase-qt4-build-cleaned-test/qtbase/demo/sliders.R')
Program received signal SIGSEGV, Segmentation fault.
0x67895282 in ZrsR11QDataStreamR12QPaintBuffer () from C:\Qt\4.8.6\bin\QtGui4.dll

(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

tsieger commented 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
lawremi commented 10 years ago

Probably related to the event loop issues. Too many threads.

tsieger commented 10 years ago

Do you think it can be solved (in near future)? Or would some workaround help temporarily?

lawremi commented 10 years ago

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.

tsieger commented 10 years ago

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
lawremi commented 10 years ago

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.

tsieger commented 10 years ago

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 ?? ()
lawremi commented 10 years ago

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.

tsieger commented 10 years ago

I'm ready to help with testing, limited debugging etc.

lawremi commented 10 years ago

Do you have the process for building it documented somewhere? I will just follow that and start debugging things. Thanks!

tsieger commented 10 years ago

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.

tsieger commented 10 years ago

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...]
tsieger commented 9 years ago

Just curious about the status - any news, please? Thanks.

tsieger commented 9 years ago

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.

lawremi commented 9 years ago

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.

lawremi commented 9 years ago

I promise to look into this over the holidays.

tsieger commented 9 years ago

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.

lawremi commented 9 years ago

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.

lawremi commented 9 years ago

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?

tsieger commented 9 years ago

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).

tsieger commented 9 years ago

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?

lawremi commented 9 years ago

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?

tsieger commented 9 years ago

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?

lawremi commented 9 years ago

Never done it before, but I think you can pass -DCMAKE_BUILD_TYPE=DEBUG to the cmake command from the Makefile.

tsieger commented 9 years ago

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.

lawremi commented 9 years ago

The dependency walker tool may offer some clues.

tsieger commented 9 years ago

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?

lawremi commented 9 years ago

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!

tsieger commented 9 years ago

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.

lawremi commented 9 years ago

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.

tsieger commented 9 years ago

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

lawremi commented 9 years ago

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.

tsieger commented 9 years ago

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.

lawremi commented 9 years ago

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.

lawremi commented 9 years ago

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.

tsieger commented 9 years ago

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?

lawremi commented 9 years ago

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.

tsieger commented 9 years ago

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.

lawremi commented 9 years ago

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.

tsieger commented 9 years ago

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
lawremi commented 9 years ago

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.

pierrebai-adsk commented 2 years ago

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.