ipe icon indicating copy to clipboard operation
ipe copied to clipboard

Ipe segfaults when editing a label for which LaTeX is still running

Open Willem3141 opened this issue 5 months ago • 3 comments

I ran into the following crash with Ipe 7.2.30 (Qt UI, on Ubuntu 24.10). It happens both with the packaged version from the Ubuntu repos and with a copy I just compiled myself.

Reproduction steps:

  1. Make sure File > Automatically run Latex is turned on.
  2. Create a label, type some text in the Create text object dialog, and click Ok.
  3. Immediately (before LaTeX has had the chance to run!) hit the shortcut to open the Edit text object dialog.
  4. Edit the text again, and click Ok.

after which Ipe segfaults. Here is a screencast: https://github.com/user-attachments/assets/51a89396-15aa-4bba-a2d6-a65a237e422b

Alternatively, instead of steps 3-4, one can also:

  1. Wait until LaTeX has finished running, then copy the label and paste it somewhere else.
  2. Immediately (before LaTeX has had the chance to run!) hit the shortcut to open the Edit text object dialog for the newly pasted label.
  3. Edit the text, and click Ok.

after which Ipe segfaults. (This is how I ran into the issue originally: I was making a figure where I was copy-pasting labels frequently.)

Stacktrace:

Thread 1 "ipe" received signal SIGSEGV, Segmentation fault.
0x00007ffff7eb0bc8 in ipe::Text::setXForm (this=0x7fffe4004ca0, xform=xform@entry=0x7fffc0004980) at ipetext.cpp:586
586	  if (iXForm && --iXForm->iRefCount == 0)
(gdb) bt
#0  0x00007ffff7eb0bc8 in ipe::Text::setXForm (this=0x7fffe4004ca0, xform=xform@entry=0x7fffc0004980) at ipetext.cpp:586
#1  0x00007ffff7ee52ad in ipe::Latex::updateTextObjects (this=this@entry=0x7fffc000b600) at ipelatex.cpp:491
#2  0x00007ffff7ee632a in ipe::Document::completeLatexRun (this=0x555555f7cde0, converter=converter@entry=0x7fffc000b600) at ipedoc.cpp:691
#3  0x00007ffff7f22ef0 in document_completeLatexRun (L=0x5555555c31c8) at ipelib.cpp:353
#4  0x00007ffff7deb5ea in precallC (f=<optimized out>, nresults=0, func=0x555555f6f360, L=0x5555555c31c8) at /build/lua5.4-GCEpSw/lua5.4-5.4.6/src/ldo.c:529
#5  luaD_precall (L=0x5555555c31c8, func=<optimized out>, nresults=0) at /build/lua5.4-GCEpSw/lua5.4-5.4.6/src/ldo.c:595
#6  0x00007ffff7df8673 in luaV_execute (L=<optimized out>, ci=<optimized out>) at /build/lua5.4-GCEpSw/lua5.4-5.4.6/src/lvm.c:1684
#7  0x00007ffff7debf6e in ccall (inc=65537, nResults=0, func=<optimized out>, L=0x5555555c31c8) at /build/lua5.4-GCEpSw/lua5.4-5.4.6/src/ldo.c:637
#8  luaD_callnoyield (nResults=0, func=<optimized out>, L=0x5555555c31c8) at /build/lua5.4-GCEpSw/lua5.4-5.4.6/src/ldo.c:655
#9  lua_callk (L=0x5555555c31c8, nargs=<optimized out>, nresults=0, ctx=<optimized out>, k=<optimized out>) at /build/lua5.4-GCEpSw/lua5.4-5.4.6/src/lapi.c:1020
#10 0x000055555556d80b in LuaTool::mouseButton (this=0x555555e69ba0, button=1, press=true) at tools.cpp:118
#11 0x00007ffff7f78f8b in ipe::Canvas::mouseButton (this=0x5555559efc90, ev=0x7fffffffd340, button=1, press=press@entry=true) at ipecanvas_qt.cpp:212
#12 0x00007ffff7f78fe5 in ipe::Canvas::mousePressEvent (this=<optimized out>, ev=<optimized out>) at ipecanvas_qt.cpp:224
#13 0x00007ffff77e30e7 in QWidget::event (this=0x5555559efc90, event=0x7fffffffd340) at /usr/src/qt6-base-6.6.2+dfsg-12/src/widgets/kernel/qwidget.cpp:8955
#14 0x00007ffff7793260 in QApplicationPrivate::notify_helper (this=this@entry=0x5555555c2fe0, receiver=receiver@entry=0x5555559efc90, e=e@entry=0x7fffffffd340)
    at /usr/src/qt6-base-6.6.2+dfsg-12/src/widgets/kernel/qapplication.cpp:3296
#15 0x00007ffff77975fe in QApplication::notify (this=<optimized out>, receiver=0x5555559efc90, e=0x7fffffffd340)
    at /usr/src/qt6-base-6.6.2+dfsg-12/src/widgets/kernel/qapplication.cpp:2782
#16 0x00007ffff6966718 in QCoreApplication::notifyInternal2 (receiver=0x5555559efc90, event=0x7fffffffd340)
    at /usr/src/qt6-base-6.6.2+dfsg-12/src/corelib/kernel/qcoreapplication.cpp:1121
[... etc.]

The crash seems caused by iXForm being invalid, but not nullptr:

(gdb) f 0
#0  0x00007ffff7eb0bc8 in ipe::Text::setXForm (this=0x7fffe4004ca0, xform=xform@entry=0x7fffc0004980) at ipetext.cpp:586
586	  if (iXForm && --iXForm->iRefCount == 0)
(gdb) p iXForm
$1 = (ipe::Text::XForm *) 0x130

Somehow 0x130 gets written to iXForm, although I don't know how that is possible.

Willem3141 avatar Jul 18 '25 15:07 Willem3141

I cannot reproduce the problem on my current development version (which is more or less what the 7.3.1 release will look like).

So it could be that the problem is cause by your Qt being newer (I'm still on Qt 6.4.2), or the problem is fixed by changes I made (the handling of the background Latex was completely rewritten to use Lua coroutines). If you have time for that, you could checkout the current version and compile that. Otherwise I hope to get to release 7.3.1 soon.

otfried avatar Jul 21 '25 13:07 otfried

Similar issue here, with segfaults and core dumps:

Warning: Ignoring WAYLAND_DISPLAY on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.
Segmentation fault (core dumped)

Warning: Ignoring WAYLAND_DISPLAY on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.
attempt to yield across a C-call boundary
stack traceback:
	[C]: in function 'coroutine.yield'
	/usr/local/share/ipe/7.3.1/lua/model.lua:302: in method 'waitDialog'
	/usr/local/share/ipe/7.3.1/lua/model.lua:596: in method 'runLatex'
	/usr/local/share/ipe/7.3.1/lua/tools.lua:1416: in function 'apply_text_edit'
	/usr/local/share/ipe/7.3.1/lua/tools.lua:1436: in function </usr/local/share/ipe/7.3.1/lua/tools.lua:1436>
	[C]: in function 'coroutine.yield'
	[string "return function (d, s, l)done, accepted = d:e..."]:1: in method 'execute'
	/usr/local/share/ipe/7.3.1/lua/tools.lua:1459: in method 'action_edit_text'
	/usr/local/share/ipe/7.3.1/lua/tools.lua:1533: in local 'f'
	/usr/local/share/ipe/7.3.1/lua/actions.lua:76: in method 'action'
	/usr/local/share/ipe/7.3.1/lua/properties.lua:85: in method 'singlePopup'
	/usr/local/share/ipe/7.3.1/lua/properties.lua:47: in method 'propertiesPopup'
	/usr/local/share/ipe/7.3.1/lua/tools.lua:1348: in local 'r'
	/usr/local/share/ipe/7.3.1/lua/tools.lua:1378: in function </usr/local/share/ipe/7.3.1/lua/tools.lua:1352>
	[C]: in function 'xpcall'
	/usr/local/share/ipe/7.3.1/lua/model.lua:164: in function </usr/local/share/ipe/7.3.1/lua/model.lua:163>
ipe: ../../../../src/cairo-hash.c:217: _cairo_hash_table_destroy: Assertion `hash_table->live_entries == 0' failed.
Aborted (core dumped)

rickbeeloo avatar Aug 14 '25 11:08 rickbeeloo

I cannot reproduce the problem on my current development version (which is more or less what the 7.3.1 release will look like).

So it could be that the problem is cause by your Qt being newer (I'm still on Qt 6.4.2), or the problem is fixed by changes I made (the handling of the background Latex was completely rewritten to use Lua coroutines). If you have time for that, you could checkout the current version and compile that. Otherwise I hope to get to release 7.3.1 soon.

Sorry for the slow reply. I just compiled the current master branch to test. It seems that the segfault is gone. Instead I'm getting this console output:

DANGER! THIS SHOULD NOT HAPPEN! Calling into Lua while an operation is ongoing. What's going on?

This is obviously much better than segfaulting, but I don't know if it has unexpected consequences? The GUI seems to keep working just fine in any case.

Willem3141 avatar Aug 18 '25 09:08 Willem3141