PDA

View Full Version : Write access violation while attaching QwtPlotCurve?



Khaine
20th April 2016, 18:30
Today I encountered access violation bug, that I can't fix by any means.

First of all - our program is using Qt plugin system. Part using Qwt is a plugin that will allow user to plot insides of dataset. And everything works fine and stable - unless we want to reload plugins. What it actually means - we just delete everything created by all plugins and create it from scratch again, just like it was the first time when program starts. So in this case my class using Qwt (inheriting QwtPlot) is destroyed, everything in it is destroyed, and then everything else somehow involved is destroyed. When we are done cleaning plot plugin is created again.

And algorithm causing this looks like that:

1. We start program, load dataset and plot one or more curves:

11901

If we don't plot anything (no QwtPlotCurve was attached to plot) - bug will not appear. Plugin will be entirely destroyed, reloaded and it will work fine.

2. We reload plugin (destroy it entirely and make new identical one).

3. When we want to attach curve to the plot, so we can see it - write access violation appears.

We suppose that it may somehow involve Qwt itself (item attaching to be precise), because we are nearly sure that everything is deleted properly.

It looks like everything starts here:
http://s31.postimg.org/3snicrhy3/bug6.png (http://postimg.org/image/iom1kctcn/full/)

QwtPlotWithFunctions is a class inheriting QwtPlot. In drawSignal we go past setSamples, so data given to curve is most probably (well, it always was) correct. When we reach attachment - this is for sure the place where everything starts to fall apart. We tested push_back marked by arrow and we are sure that program crashes on attachment. curves is a QVector containing pointers to QwtPlotCurves - they are created in memory when we load dataset, so there are as many curves as there are signals possible to plot.

Then debugger lead us further:

http://s31.postimg.org/z9om2we57/bug3.png (http://postimg.org/image/frtymyh7b/full/)

http://s31.postimg.org/py7m327x7/bug2.jpg (http://postimg.org/image/mrd2jfnh3/full/)

http://s31.postimg.org/501g4z82j/bug1.jpg (http://postimg.org/image/yf74dzclz/full/)

And it looks like everything ends up when qVariantSetValue is called. I uploaded only last 3 things debugger shows, because of limit of 4 images per post. I may upload the rest if you wish.

What may cause this kind of bug and where should we look for solution?

Aningan
20th April 2016, 18:54
Hi everyone, I work on this project with Khaine and wanted to clarify our problem a bit.
To add more about the plugin reloading part - we destroy the plugin using QPluginLoader::unload() and delete loader object afterwards. We are aware of an issue described in this topic on SO (http://stackoverflow.com/questions/15300812/why-does-memory-allocated-from-inside-a-dll-become-invalid-after-freelibrary) which causes difficult to debug crashes when trying to access objects left undeleted by unmounted plugin, Windows OS (experienced it with our other plugins) - I mention it as it might be the case, but do not think it actually happens now.

Uwe
21st April 2016, 07:17
And it looks like everything ends up when qVariantSetValue is called.
What may cause this kind of bug and where should we look for solution?
The crash happens while wrapping a QwtText into a QVariant - both temporary objects on the stack, that should be unrelated to loading/unloading plugins. So I would indeed have a deeper look at the code of qVariantSetValue and maybe the Q_DECLARE_METATYPE(QwtText) macro.

Beside that be aware of QwtText::textEngine(). The text engines are created when being used first and will never be destroyed.

Uwe

Khaine
21st April 2016, 11:18
EDIT:

http://stackoverflow.com/questions/27527041/handling-qmetatype-registration-in-qt5-with-dynamic-plug-ins

Thanks Uwe, we did some research on Q_DECLARE_METATYPE. It looks like unloading plugins is not even supported in Qt5, so we have to disable this feature anyway which will make problem not-existant. It looks like this problem was most likely related to unloading plugins. It looks like declaring class in QtMetaType system that was declared in already unmounted .dll causes QVariant to not work properly. In our case QwtText has type 1044 and it's probably declared second time after reload.