I did some investigation of this, and maybe we can fix it before we land. It is pretty nasty.

Here's the backtrace:

0 raise raise.c 64 0x3726c330c5
1 abort abort.c 92 0x3726c34a76
2 lyx::lyx_exit LyX.cpp 236 0x510568
3 boost::assertion_failed boost.cpp 47 0x460e5d
4 lyx::doAssert lassert.cpp 37 0x9cc69e
5 lyx::Paragraph::getFontSettings Paragraph.cpp 1712 0x551da2
6 lyx::TextMetrics::displayFont TextMetrics? <http://www.lyx.org/trac/wiki/TextMetrics>.cpp 254 0x59b58b 7 lyx::TextMetrics::isRTL TextMetrics? <http://www.lyx.org/trac/wiki/TextMetrics>.cpp 301 0x59b91b 8 lyx::BufferView::coordOffset BufferView? <http://www.lyx.org/trac/wiki/BufferView>.cpp 2610 0x5d17a8 9 lyx::BufferView::getPos BufferView? <http://www.lyx.org/trac/wiki/BufferView>.cpp 2685 0x5d1a75
10 lyx::Cursor::getPos Cursor.cpp 486 0x5ea43a
11 lyx::Cursor::targetX Cursor.cpp 1664 0x5eb702
12 lyx::InsetTabular::doDispatch InsetTabular? <http://www.lyx.org/trac/wiki/InsetTabular>.cpp 4079 0x79a528
13 lyx::Inset::dispatch Inset.cpp 314 0x6d8b66
14 lyx::Cursor::dispatch Cursor.cpp 368 0x5f4bba

As the bug report notes, you do NOT get this crash if you move up or down in the table a bit before you do the rest. The reason is that moving up and down sets the cursor's x_target_, and it is because that is not set that we enter the other code at all and eventually crash. That is, at (12), we have:

(*) cur.pos() = tm.x2pos(cur.pit(), pm.rows().size()-1, cur.targetX());

You can see the potential for trouble here already. cur.pit() is in the NEW cell, i.e., the one to which we are moving; it was changed a few lines previously, and cur.idx() points to the new cell, too. But we are trying to calculate cur.pos(), which means that cur.pos() is currently the one from the OLD cell. So the cursor is in an inconsistent state. Calling cur.targetX() leads us to call Cursor::getPos(), and that is what causes the crash.

The attached fixes the problem by making sure we call targetX() on the original cursor. The same problem clearly exists in the DOWN stuff.

By the way, should we be setting x_target_ here once we have calculated it? I do not understand this code very well.

Richard


Index: src/insets/InsetTabular.cpp
===================================================================
--- src/insets/InsetTabular.cpp (revision 38514)
+++ src/insets/InsetTabular.cpp (working copy)
@@ -4036,11 +4036,12 @@
                        // setting also the right targetX.
                        cur.selHandle(act == LFUN_DOWN_SELECT);
                        if (tabular.cellRow(cur.idx()) != tabular.nrows() - 1) {
+                               int const xtarget = cur.targetX();
                                cur.idx() = tabular.cellBelow(cur.idx());
                                cur.pit() = 0;
                                TextMetrics const & tm =
                                        
cur.bv().textMetrics(cell(cur.idx())->getText(0));
-                               cur.pos() = tm.x2pos(cur.pit(), 0, 
cur.targetX());
+                               cur.pos() = tm.x2pos(cur.pit(), 0, xtarget);
                                cur.setCurrentFont();
                        }
                }
@@ -4070,13 +4071,14 @@
                        // setting also the right targetX.
                        cur.selHandle(act == LFUN_UP_SELECT);
                        if (tabular.cellRow(cur.idx()) != 0) {
+                               int const xtarget = cur.targetX();
                                cur.idx() = tabular.cellAbove(cur.idx());
                                cur.pit() = cur.lastpit();
                                Text const * text = cell(cur.idx())->getText(0);
                                TextMetrics const & tm = 
cur.bv().textMetrics(text);
                                ParagraphMetrics const & pm =
                                        tm.parMetrics(cur.lastpit());
-                               cur.pos() = tm.x2pos(cur.pit(), 
pm.rows().size()-1, cur.targetX());
+                               cur.pos() = tm.x2pos(cur.pit(), 
pm.rows().size()-1, xtarget);
                                cur.setCurrentFont();
                        }
                }

Reply via email to