Results 1 to 12 of 12

Thread: Longstanding problem with crashing, 'pure virtual function call'

  1. #1
    Join Date
    Aug 2009
    Posts
    140
    Thanks
    22
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Longstanding problem with crashing, 'pure virtual function call'

    Hi,

    I'm just plotting a couple of curves on a canvas. This problem happens when the number of samples in the curves is very high >100,000--and not when its more like 1000. Basically the program will draw for a little while, then crash with the pure virtual function call error message (which I think just indicates corrupted memory) and output like this:

    QWidget::repaint: Recursive repaint detected
    QPainter::begin: A paint device can only be painted by one painter at a time.
    QPainter::translate: Painter not active
    QPainter::begin: A paint device can only be painted by one painter at a time.
    QPainter::save: Painter not active
    QPainter::setClipRect: Painter not active
    QPainter::save: Painter not active
    QPainter::setRenderHint: Painter must be active to set rendering hints
    QPainter::setRenderHint: Painter must be active to set rendering hints
    QPainter::restore: Unbalanced save/restore
    QPainter::save: Painter not active
    QPainter::setRenderHint: Painter must be active to set rendering hints
    QPainter::setRenderHint: Painter must be active to set rendering hints
    QPainter::save: Painter not active
    QPainter::setPen: Painter not active
    QPainter:en: Painter not active
    QPainter::restore: Unbalanced save/restore
    QPainter::restore: Unbalanced save/restore
    QPainter::save: Painter not active
    ...
    My replot is activated by a timer, so it could be that replot is being called before the widget is finished drawing from the previous call. So how do I tell the QwtPlot to wait, or to skip this round? With some of these curves I really lose important information if I simply subsample, so that's not a good option for me.

    Matt

  2. #2
    Join Date
    Dec 2013
    Location
    Toronto, Canada
    Posts
    62
    Thanked 16 Times in 15 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Longstanding problem with crashing, 'pure virtual function call'

    I am not sure why you would want to call replot() periodically via a timer. Did you try setAutoReplot()

  3. #3
    Join Date
    Aug 2009
    Posts
    140
    Thanks
    22
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Longstanding problem with crashing, 'pure virtual function call'

    I do this because I do the calculations behind the data display in a worker thread, and call replot() when they are done. I use a Qt::BlockingQueuedConnection for this and have an assert() statement which guarantees that replot() is only ever getting called from the main thread.

    I did try setAutoReplot(), and commented out my call to replot(), but the program crashed immediately, segfaulting in QwtPlot::drawItems. I also got this warning: "QCoreApplication::sendPostedEvents: Cannot send posted events for objects in another thread".
    Last edited by MattPhillips; 11th August 2014 at 15:28.

  4. #4
    Join Date
    Dec 2013
    Location
    Toronto, Canada
    Posts
    62
    Thanked 16 Times in 15 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Longstanding problem with crashing, 'pure virtual function call'

    Is the calculation time dependent...
    Are you doing some sort of sampling...
    How about qwtsamplethread...

  5. #5
    Join Date
    Aug 2009
    Posts
    140
    Thanks
    22
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Longstanding problem with crashing, 'pure virtual function call'

    What is QwtSampleThread? I couldn't find that anywhere. I don't know what you mean by 'time-dependent', of course, the calculation takes some time. The timer doesn't fire until after it's complete though, so 100ms is a lower bound on the interval between repaints.

  6. #6
    Join Date
    Dec 2013
    Location
    Toronto, Canada
    Posts
    62
    Thanked 16 Times in 15 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Longstanding problem with crashing, 'pure virtual function call'

    What is QwtSampleThread
    My mistake ... It's QwtSamplingThread and not QwtSampleThread

    I don't know what you mean by 'time-dependent', of course, the calculation takes some time
    I had a look at my post and do understand the confusion. What I wanted to know is if time is the independent variable (time vs dependent_variable)

    I am still no clear why you need the help of a separate thread for calculation.

  7. #7
    Join Date
    Aug 2009
    Posts
    140
    Thanks
    22
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Longstanding problem with crashing, 'pure virtual function call'

    Yes, time is generally the independent variable, but what the data represent is immaterial, or have I still not understood you? Basically the program runs a numerical simulation, and the evolution of the state variables is displayed as they evolve.

    I use a separate thread for calculation for the usual reason--I don't want the gui blocked while the calculations are taking place. The user needs to be able to adjust parameters, etc. as the simulation progresses.

  8. #8
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Longstanding problem with crashing, 'pure virtual function call'

    When I'm implementing similar situations I usually use a timer in the GUI thread, that periodically checks a flag + calling replot when it has been set + clears the flag. The worker thread does nothing beside its job + setting the flag, when it has delivered something new.

    Uwe

  9. #9
    Join Date
    Aug 2009
    Posts
    140
    Thanks
    22
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Longstanding problem with crashing, 'pure virtual function call'

    Hi Uwe,

    Is the problem that I create and attach QwtPlotItems to QwtPlots within a worker thread? Do you do this? My intuition had been that calling replot from a worker thread could fail but just making the objects could be done anywhere. Otherwise, what you're saying sounds just like what I do, except that in your case the timer is in the main thread whereas in mine it's in the worker thread, which shouldn't make any difference.

  10. #10
    Join Date
    Dec 2013
    Location
    Toronto, Canada
    Posts
    62
    Thanked 16 Times in 15 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Longstanding problem with crashing, 'pure virtual function call'

    I believe signal emission is always thread-safe.

    Qt Code:
    1. class CalculationThread : public QThread
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. CalculationThread(QObject *parent = 0);
    7. ~CalculationThread();
    8.  
    9. void calculation(CalculationData & data);
    10. void run();
    11.  
    12. signals:
    13. void dataChanged();
    14. void error(const QString &message);
    15.  
    16. private:
    17. ...
    18. CalculationData m_data
    19. QMutex mutex;
    20. ...
    21. };
    22.  
    23.  
    24. void CalculationThread::calculation(CalculationData & data)
    25. {
    26. QMutexLocker locker(&mutex);
    27. m_data = data;
    28. if (!isRunning())
    29. start();
    30. ...
    31. }
    32.  
    33.  
    34. void CalculationThread::run()
    35. {
    36. mutex.lock();
    37.  
    38. ...
    39. //do time consuming calculations
    40. ...
    41.  
    42. if(/*data changed*/)
    43. emit dataChanged();
    44. mutex.unlock();
    45. }
    46.  
    47.  
    48. class Plot: public QwtPlot
    49. {
    50. ...
    51.  
    52. private slots:
    53. dataChangedCalc()
    54.  
    55. }
    56.  
    57. Plot::dataChangedCalc()
    58. {
    59. ...
    60. // create and attach QwtPlotItems to QwtPlots
    61. ...
    62. this->replot()
    63.  
    64. }
    65.  
    66.  
    67. connect(&thread, SIGNAL(dataChanged()), this, SLOT(dataChangedCalc()));
    To copy to clipboard, switch view to plain text mode 

    Note: the this pointer is a pointer to a Plot


    Is the problem that I create and attach QwtPlotItems to QwtPlots within a worker thread?
    I assuming that you are creating and attaching many plotItems (that's your motivation for putting this activity in the worker thread)
    QObject and subclasses thereof are not thread safe. QwtPlot is asubclas of QObject.

  11. #11
    Join Date
    Aug 2009
    Posts
    140
    Thanks
    22
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Longstanding problem with crashing, 'pure virtual function call'

    Cah,

    Yes, this is what it looks like I will have to try. My version of the '// create and attach QwtPlotItems to QwtPlots' part of 'dataChangedCalc' is in the worker thread; only the replot is in the mean thread. My hope is to gain some insight in advance as to whether this really should make the critical difference--see my previous post--but not knowing any other reasonable possibility I'll probably just try this in any case. Maybe you're right and it's the non-thread-safety of QwtPlot that's getting me; I only have one worker thread on the QwtPlot in question but maybe OS-generated calls to replot are causing the problem. I'll post my results in this thread when I have them.

  12. #12
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Longstanding problem with crashing, 'pure virtual function call'

    Attaching/detaching items from a different thread is definitely not thread safe !

    To make it safe you would have at least to introduce a mutex to avoid that attaching/detaching and iterating over the items in the replot operation do conflict.

    For guarding the replot it is probably best to overload QwtPlot::replot(), where you do the mutex stuff before calling the base class.

    Uwe

Similar Threads

  1. QGraphicsItem: pure virtual method call problem
    By phuongot in forum Qt Programming
    Replies: 5
    Last Post: 17th January 2012, 08:35
  2. Replies: 10
    Last Post: 29th May 2009, 10:06
  3. Replies: 16
    Last Post: 13th March 2008, 18:46
  4. Cost of pure virtual
    By ShaChris23 in forum General Programming
    Replies: 4
    Last Post: 4th November 2007, 19:20
  5. virtual overloaded functions and base class function call...
    By nouknouk in forum General Programming
    Replies: 7
    Last Post: 11th March 2006, 22:26

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.