SUMMARY STEPS TO REPRODUCE 1. FreeBSD 11.4-p2, install kmplot from pkg [quarterly repo] 2. Lauch kmplot and plot any implicit functions include tangent 3. For example: tan(x+y)=tan(x)+tan(y), hit enter OBSERVED RESULT The program crashed immediately and give a core dump EXPECTED RESULT It used to work fine with these functions SOFTWARE/OS VERSIONS Windows: macOS: Linux/KDE Plasma: (available in About System) KDE Plasma Version: KDE Frameworks Version: Qt Version: ADDITIONAL INFORMATION Check all of these information on freshports: https://www.freshports.org/math/kmplot/
The example reproduces the crash, but isn't useful. Which actual implicit function did you want to plot that shows the crash?
(In reply to Christoph Feck from comment #1) > The example reproduces the crash, but isn't useful. Which actual implicit > function did you want to plot that shows the crash? What is useful I wonder? I found a website of good looking functions graphs of a Math prof and it contains many implicit functions. I tried to graph them using kmplot and many of them contain tangent and cotangent. It's a critical bug because any implicit functions that have tangent or cotangent caused kmplot to crash and core dump immediately. Additional info: I downloaded ROSA Linux and use their KDE4 version. I could sure that the KDE4's kmplot could deal with these kind of functions without any problems. Only the current KDE5 based kmplot has trouble with them.
Could you point me to this website?
Thank you for reporting this crash in KDE software. As it has been a while since this issue was reported, can we please ask you to see if you can reproduce the crash with a recent software version? If you can reproduce the issue, please change the status to "CONFIRMED" when replying. Thank you!
Crash still reproducible with "tan(x+y)=tan(x)+tan(y)" implicit function. (gdb) bt #0 0x00007fffe80b702d in Parser::number (value=<error reading variable: Cannot access memory at address 0x3500330036002e>) at /usr/src/debug/kmplot-22.11.70git.20221003T020421~a69f00b-ku.6.1.x86_64/kmplot/parser.cpp:1171 #1 View::drawImplicit (this=<optimized out>, function=0x555556138470, painter=<optimized out>) at /usr/src/debug/kmplot-22.11.70git.20221003T020421~a69f00b-ku.6.1.x86_64/kmplot/view.cpp:1176 #2 0x00007fffe80bdb8e in View::draw (this=0x555555bed120, dev=<optimized out>, medium=<optimized out>) at /usr/src/debug/kmplot-22.11.70git.20221003T020421~a69f00b-ku.6.1.x86_64/kmplot/view.cpp:363 #3 0x00007fffe80aa70d in View::draw (medium=View::Screen, dev=0x555555bed2a8, this=0x555555bed120) at /usr/src/debug/kmplot-22.11.70git.20221003T020421~a69f00b-ku.6.1.x86_64/kmplot/view.cpp:2637 #4 View::drawPlot (this=0x555555bed120) at /usr/src/debug/kmplot-22.11.70git.20221003T020421~a69f00b-ku.6.1.x86_64/kmplot/view.cpp:2636 #5 0x00007fffe80986b6 in FunctionEditor::saveImplicit (this=0x55555588ed90) at /usr/src/debug/kmplot-22.11.70git.20221003T020421~a69f00b-ku.6.1.x86_64/kmplot/functioneditor.cpp:639 #6 0x00007ffff6712fcd in QtPrivate::QSlotObjectBase::call (a=0x7fffffffd1c0, r=0x55555588ed90, this=0x55555583faa0) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398 #7 doActivate<false> (sender=0x55555583f6b0, signal_index=3, argv=0x7fffffffd1c0) at kernel/qobject.cpp:3919 #8 0x00007ffff670c44f in QMetaObject::activate (sender=<optimized out>, m=m@entry=0x7ffff69b39e0, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7fffffffd1c0) at kernel/qobject.cpp:3979 #9 0x00007ffff6716e0a in QTimer::timeout (this=<optimized out>, _t1=...) at .moc/moc_qtimer.cpp:205
still happens on current head ( a89ed5ddfea2ac96cfdce2bc4d1b49f268065edd ) - that pointer value is obviously complete garbage: #0 0x00007fffdd0d6e1d in Parser::number(double) (value=Python Exception <class 'gdb.MemoryError'>: Cannot access memory at address 0x34003600360031 looks like someone is writing ascii where a pointer should be.
I think I kind of understand what's going on, but not 100% and hmm. void View::drawImplicit(Function *function, QPainter *painter) { .... QList<QPointF> singular; ... for (const QPointF &point : qAsConst(singular)) { ... for (double t : qAsConst(roots)) { double x = point.x() + epsilon * lcos(t); double y = point.y() + epsilon * lsin(t); drawImplicitInSquare(plot, painter, x, y, {}, &singular); } so, 'singular' - which I think is a list being walked in the outer for, gets modified by 'drawImplicitInSquare' in a corner case - which I think is the fact tan is not-contiguous. I think turning that loop into a QMutableListIterator might work.
Hmm the QMutableListIterator didn't work and I've not figured out why yet; the valgrind I'm looking at is: ==39870== Invalid read of size 8 ==39870== at 0x1DEF2D01: UnknownInlinedFun (qlist.h:153) ==39870== by 0x1DEF2D01: UnknownInlinedFun (qlist.h:313) ==39870== by 0x1DEF2D01: View::drawImplicit(Function*, QPainter*) (view.cpp:1168) ==39870== by 0x1DEF997D: View::draw(QPaintDevice*, View::PlotMedium) [clone .part.0] (view.cpp:363) ==39870== by 0x1DEE62D4: UnknownInlinedFun (view.cpp:2637) ==39870== by 0x1DEE62D4: View::drawPlot() (view.cpp:2636) ==39870== by 0x1DED4129: FunctionEditor::saveImplicit() (functioneditor.cpp:639) ==39870== by 0x5E5DE95: call (qobjectdefs_impl.h:398) ==39870== by 0x5E5DE95: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3923) ==39870== by 0x5E6121D: QTimer::timeout(QTimer::QPrivateSignal) (moc_qtimer.cpp:205) ==39870== by 0x5E54FC4: QObject::event(QEvent*) (qobject.cpp:1369) ==39870== by 0x4FA2D61: QApplicationPrivate::notify_helper(QObject*, QEvent*) (qapplication.cpp:3640) ==39870== by 0x5E2A4E7: QCoreApplication::notifyInternal2(QObject*, QEvent*) (qcoreapplication.cpp:1064) ==39870== by 0x5E7A980: QTimerInfoList::activateTimers() (qtimerinfo_unix.cpp:643) ==39870== by 0x5E7B25B: timerSourceDispatch(_GSource*, int (*)(void*), void*) (qeventdispatcher_glib.cpp:183) ==39870== by 0x78C2C7E: UnknownInlinedFun (gmain.c:3454) ==39870== by 0x78C2C7E: g_main_context_dispatch (gmain.c:4172) ==39870== Address 0x2d53d948 is 40 bytes inside a block of size 120 free'd ==39870== at 0x48486AF: realloc (vg_replace_malloc.c:1451) ==39870== by 0x5CB2156: QListData::realloc_grow(int) (qlist.cpp:170) ==39870== by 0x5CB2201: QListData::append(int) (qlist.cpp:196) ==39870== by 0x1DEF507C: UnknownInlinedFun (qlist.h:632) ==39870== by 0x1DEF507C: QList<QPointF>::append(QPointF const&) (qlist.h:620) ==39870== by 0x1DEEC03F: UnknownInlinedFun (qlist.h:402) ==39870== by 0x1DEEC03F: View::drawImplicitInSquare(Plot const&, QPainter*, double, double, QFlags<Qt::Orientation>, QList<QPointF>*) (view.cpp:1358) ==39870== by 0x1DEF33D5: View::drawImplicit(Function*, QPainter*) (view.cpp:1199) ==39870== by 0x1DEF997D: View::draw(QPaintDevice*, View::PlotMedium) [clone .part.0] (view.cpp:363) ==39870== by 0x1DEE62D4: UnknownInlinedFun (view.cpp:2637) ==39870== by 0x1DEE62D4: View::drawPlot() (view.cpp:2636) ==39870== by 0x1DED4129: FunctionEditor::saveImplicit() (functioneditor.cpp:639) ==39870== by 0x5E5DE95: call (qobjectdefs_impl.h:398) ==39870== by 0x5E5DE95: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3923) ==39870== by 0x5E6121D: QTimer::timeout(QTimer::QPrivateSignal) (moc_qtimer.cpp:205) ==39870== by 0x5E54FC4: QObject::event(QEvent*) (qobject.cpp:1369) ==39870== Block was alloc'd at ==39870== at 0x484386F: malloc (vg_replace_malloc.c:393) ==39870== by 0x5CB207F: QListData::detach(int) (qlist.cpp:137) ==39870== by 0x1DEF3D0E: UnknownInlinedFun (qlist.h:833) ==39870== by 0x1DEF3D0E: UnknownInlinedFun (qlist.h:613) ==39870== by 0x1DEF3D0E: UnknownInlinedFun (qmap.h:1028) ==39870== by 0x1DEF3D0E: View::drawImplicit(Function*, QPainter*) (view.cpp:1166) ==39870== by 0x1DEF997D: View::draw(QPaintDevice*, View::PlotMedium) [clone .part.0] (view.cpp:363) ==39870== by 0x1DEE62D4: UnknownInlinedFun (view.cpp:2637) ==39870== by 0x1DEE62D4: View::drawPlot() (view.cpp:2636) ==39870== by 0x1DED4129: FunctionEditor::saveImplicit() (functioneditor.cpp:639) ==39870== by 0x5E5DE95: call (qobjectdefs_impl.h:398) ==39870== by 0x5E5DE95: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3923) ==39870== by 0x5E6121D: QTimer::timeout(QTimer::QPrivateSignal) (moc_qtimer.cpp:205) ==39870== by 0x5E54FC4: QObject::event(QEvent*) (qobject.cpp:1369) ==39870== by 0x4FA2D61: QApplicationPrivate::notify_helper(QObject*, QEvent*) (qapplication.cpp:3640) ==39870== by 0x5E2A4E7: QCoreApplication::notifyInternal2(QObject*, QEvent*) (qcoreapplication.cpp:1064) ==39870== by 0x5E7A980: QTimerInfoList::activateTimers() (qtimerinfo_unix.cpp:643) ==39870==
Unfortunately QMutableListIterator doesn't cope with growing the list either; so it needs a larger rework.
A possibly relevant merge request was started @ https://invent.kde.org/education/kmplot/-/merge_requests/13
I've just created: https://invent.kde.org/education/kmplot/-/merge_requests/13 for this. It seems to clear the crash; I'm not 100% sure I understand all the details of that function though - but I think I'm just fixing it's list manipulation. (Note there are other problems with this program; like the fact that it refreshes the graph as you type and the smallest typo, or it refreshing as you type part of the equation can mean it takes minutes locking up X in that function to do the graph plotting)