Results 1 to 4 of 4

Thread: Segfault when calling setAxisScaleEngine more than 2 times

  1. #1
    Join Date
    Oct 2009
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Segfault when calling setAxisScaleEngine more than 2 times

    I have a program where I want to be able to switch between a logarithmic and linear scale. It works fine for the first couple of times, but then fails with a segmentation fault. Any pointers on what I might be doing wrong before submitting a bug report.

    Here is a sample code to reproduce the bug
    Qt Code:
    1. #include "TestQwtPlot.h"
    2. #include "TestQwtPlot.moc"
    3.  
    4. #include <QtGui/QMenu>
    5. #include <QtGui/QMenuBar>
    6. #include <QtGui/QAction>
    7. #include <qwt/qwt_plot.h>
    8. #include <qwt/qwt_scale_engine.h>
    9. #include <qwt/qwt_data.h>
    10. #include <qwt/qwt_plot_curve.h>
    11.  
    12. TestQwtPlot::TestQwtPlot()
    13. {
    14. plot = new QwtPlot(this);
    15. linScale = new QwtLinearScaleEngine();
    16. logScale = new QwtLog10ScaleEngine();
    17. double x[5] = {1,2,3,4,5};
    18. QwtArrayData qwtArray ( x, x, 5 );
    19. QwtPlotCurve *curve1 = new QwtPlotCurve ( "Curve 1" );
    20. curve1->setData ( qwtArray );
    21. curve1->attach( plot );
    22. plot->replot();
    23. QAction* log = new QAction(this);
    24. QAction* lin = new QAction(this);
    25. log->setText( "Logarithmic scale" );
    26. lin->setText( "Linear scale" );
    27. setCentralWidget(plot);
    28. QAction* a = new QAction(this);
    29. a->setText( "Quit" );
    30. connect(a, SIGNAL(triggered()), SLOT(close()) );
    31. connect(lin, SIGNAL(triggered()), SLOT(on_lin_triggered()));
    32. connect(log, SIGNAL(triggered()), SLOT(on_log_triggered()));
    33. QMenu * m = menuBar()->addMenu( "File" );
    34. m->addAction( a );
    35. m->addAction( log );
    36. m->addAction( lin );
    37. }
    38.  
    39. TestQwtPlot::~TestQwtPlot()
    40. {}
    41.  
    42. void TestQwtPlot::on_lin_triggered(){
    43. plot->setAxisScaleEngine(QwtPlot::yLeft, linScale);
    44. plot->setAxisScaleEngine(QwtPlot::xBottom, linScale);
    45. plot->replot();
    46. }
    47.  
    48. void TestQwtPlot::on_log_triggered(){
    49. plot->setAxisScaleEngine(QwtPlot::yLeft, logScale);
    50. plot->setAxisScaleEngine(QwtPlot::xBottom, logScale);
    51. plot->replot();
    52. }
    To copy to clipboard, switch view to plain text mode 

    and the header

    Qt Code:
    1. #ifndef TestQwtPlot_H
    2. #define TestQwtPlot_H
    3.  
    4. #include <QtGui/QMainWindow>
    5. #include <qwt/qwt_plot.h>
    6. #include <qwt/qwt_scale_engine.h>
    7.  
    8. class TestQwtPlot : public QMainWindow
    9. {
    10. Q_OBJECT
    11. public:
    12. TestQwtPlot();
    13. virtual ~TestQwtPlot();
    14. private:
    15. QwtPlot *plot;
    16. private slots:
    17. void on_log_triggered();
    18. void on_lin_triggered();
    19. };
    20.  
    21. #endif // TestQwtPlot_H
    To copy to clipboard, switch view to plain text mode 

    and finally the backtrace

    Qt Code:
    1. #0 0x0000000000000021 in ?? ()
    2. #1 0x00007ffff6b943b2 in QwtPlot::setAxisScaleEngine(int, QwtScaleEngine*) () from /usr/lib64/libqwt.so.5
    3. #2 0x0000000000403838 in TestQwtPlot::on_lin_triggered (this=0x7fffffffd200) at /home/gudlaugu/projects/TestQwtPlot/TestQwtPlot.cpp:44
    4. #3 0x00000000004049d8 in TestQwtPlot::qt_metacall (this=0x7fffffffd200, _c=QMetaObject::InvokeMetaMethod, _id=1, _a=0x7fffffffa9f0) at /home/gudlaugu/projects/TestQwtPlot/build/TestQwtPlot.moc:69
    5. #4 0x00007ffff7affee2 in QMetaObject::activate (sender=0x887370, from_signal_index=<value optimized out>, to_signal_index=6, argv=0x0) at kernel/qobject.cpp:3113
    6. #5 0x00007ffff6f86a37 in QAction::triggered (this=0x749d10, _t1=false) at .moc/release-shared/moc_qaction.cpp:236
    7. #6 0x00007ffff6f87eb0 in QAction::activate (this=0x887370, event=<value optimized out>) at kernel/qaction.cpp:1167
    8. #7 0x00007ffff7370ddd in QMenuPrivate::activateCausedStack (this=0x82ba90, causedStack=@0x7fffffffab10, action=0x887370, action_e=QAction::Trigger, self=true) at widgets/qmenu.cpp:967
    9. #8 0x00007ffff7376dde in QMenuPrivate::activateAction (this=0x82ba90, action=0x887370, action_e=QAction::Trigger, self=true) at widgets/qmenu.cpp:1060
    10. #9 0x00007ffff6fdda3d in QWidget::event (this=0x72f5a0, event=0x7fffffffb2d0) at kernel/qwidget.cpp:7554
    11. #10 0x00007ffff737962b in QMenu::event (this=0x72f5a0, e=0x7fffffffb2d0) at widgets/qmenu.cpp:2358
    12. #11 0x00007ffff6f8ca4d in QApplicationPrivate::notify_helper (this=0x6072e0, receiver=0x72f5a0, e=0x7fffffffb2d0) at kernel/qapplication.cpp:4065
    13. #12 0x00007ffff6f9543a in QApplication::notify (this=<value optimized out>, receiver=0x72f5a0, e=0x7fffffffb2d0) at kernel/qapplication.cpp:3767
    14. #13 0x00007ffff7aeb15c in QCoreApplication::notifyInternal (this=0x7fffffffd240, receiver=0x72f5a0, event=0x7fffffffb2d0) at kernel/qcoreapplication.cpp:610
    15. #14 0x00007ffff6f94688 in QApplicationPrivate::sendMouseEvent (receiver=0x72f5a0, event=0x7fffffffb2d0, alienWidget=0x0, nativeWidget=0x72f5a0, buttonDown=<value optimized out>, lastMouseReceiver=@0x7ffff799ff30)
    16. at ../../src/corelib/kernel/qcoreapplication.h:216
    17. #15 0x00007ffff6ffe644 in QETWidget::translateMouseEvent (this=0x72f5a0, event=<value optimized out>) at kernel/qapplication_x11.cpp:4343
    18. #16 0x00007ffff6ffd4f5 in QApplication::x11ProcessEvent (this=0x7fffffffd240, event=0x7fffffffce50) at kernel/qapplication_x11.cpp:3550
    19. #17 0x00007ffff7024854 in x11EventSourceDispatch (s=0x610340, callback=0, user_data=0x0) at kernel/qguieventdispatcher_glib.cpp:146
    20. #18 0x00007ffff57970fb in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
    21. #19 0x00007ffff579a8cd in ?? () from /usr/lib64/libglib-2.0.so.0
    22. #20 0x00007ffff579aa8b in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0
    23. #21 0x00007ffff7b1456c in QEventDispatcherGlib::processEvents (this=0x60c430, flags=<value optimized out>) at kernel/qeventdispatcher_glib.cpp:407
    24. #22 0x00007ffff7023fdf in QGuiEventDispatcherGlib::processEvents (this=0x749d10, flags=<value optimized out>) at kernel/qguieventdispatcher_glib.cpp:202
    25. #23 0x00007ffff7ae99e2 in QEventLoop::processEvents (this=<value optimized out>, flags={i = -11968}) at kernel/qeventloop.cpp:149
    26. #24 0x00007ffff7ae9db4 in QEventLoop::exec (this=0x7fffffffd180, flags={i = -11888}) at kernel/qeventloop.cpp:201
    27. #25 0x00007ffff7aec0a4 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:888
    28. #26 0x0000000000404cb7 in main (argc=1, argv=0x7fffffffd338) at /home/gudlaugu/projects/TestQwtPlot/main.cpp:10
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Oct 2009
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Segfault when calling setAxisScaleEngine more than 2 times

    Replying to myself so others don't fall into this trap. The problem is that setAxisScaleEngine deletes the previously set scale engine. So my allocated engine is deleted in the second call to setAxisScaleEngine, causing the segfault. Solution is to create the scale engine before the call to setAxisScaleEngine and never delete it.

    This is not a logical behavior and I have submitted a bug report. So this might change in subsequent releases, currently using 5.2.

  3. #3
    Join Date
    Oct 2009
    Posts
    8
    Thanks
    1
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Segfault when calling setAxisScaleEngine more than 2 times

    I presume QwtPlot takes ownership of the scale engine after the call to setAxisScaleEngine. This sort of thing is standard behaviour with Qt, so I would say it is logical in this context.

    Having said that, the Qt documentation is very explicit about when ownership of an object is and is not transferred. The Qwt documentation should be updated to be very explicit about when this does and does not occur.

  4. #4
    Join Date
    Nov 2008
    Posts
    22
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11

    Default Re: Segfault when calling setAxisScaleEngine more than 2 times

    Jord,
    So what should one do to address or circumvent the behaviour? In my case, the call works only in Mac OS and not in Linux, the second call to either change the scale between Linear and Log, or change the Min and Max values is called as show here:
    Qt Code:
    1. calibPlot->setAxisScale(QwtPlot::xBottom, xMinVal.toInt(&ok,10),axisXEnd->text().toInt(&ok,10) );
    To copy to clipboard, switch view to plain text mode 
    When called to change the Scale:
    Qt Code:
    1. void CentralPage::xAxisScaleChange( const QString &xAxisScaleType)
    2. {
    3. if (xAxisScaleType == "[X]Linear") {
    4. calibPlot->setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine ());
    5. calibPlot->replot();
    6. } else {
    7. calibPlot->setAxisScaleEngine(QwtPlot::xBottom, new QwtLog10ScaleEngine());
    8. calibPlot->replot();
    9. }
    10. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Replies: 5
    Last Post: 6th March 2007, 05:34

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.