Bug 328277 - Kate crashes in Vi-mode when undoing and then pressing '.'
Summary: Kate crashes in Vi-mode when undoing and then pressing '.'
Status: RESOLVED FIXED
Alias: None
Product: kate
Classification: Applications
Component: Vi Input Mode (show other bugs)
Version: Git
Platform: Compiled Sources Linux
: NOR crash
Target Milestone: ---
Assignee: KWrite Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-12-01 13:14 UTC by Miquel Sabaté
Modified: 2013-12-04 21:33 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
The file in which I can reproduce the crash (50 bytes, text/x-csrc)
2013-12-01 13:14 UTC, Miquel Sabaté
Details
Backtrace (7.76 KB, application/octet-stream)
2013-12-01 14:56 UTC, Miquel Sabaté
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Miquel Sabaté 2013-12-01 13:14:13 UTC
I'm attaching a basic C file in which I can reproduce this crash in the master branch of Kate.

1. In normal mode, go to line 6 and select with Shift + V until line 8.
2. Indent the if statement with Shift + >, and undo this change afterwards.
3. Indent the if statement with Shift + > again.
4. Press '.', => crash

Reproducible: Always
Comment 1 Miquel Sabaté 2013-12-01 13:14:52 UTC
Created attachment 83851 [details]
The file in which I can reproduce the crash
Comment 2 Dominik Haumann 2013-12-01 14:16:03 UTC
Can you provide a backtrace and a valgrind trace?
Comment 3 Miquel Sabaté 2013-12-01 14:56:26 UTC
Created attachment 83857 [details]
Backtrace
Comment 4 Dominik Haumann 2013-12-01 14:58:34 UTC
Please always paste the backtrace:

Thread 1 (Thread 0x7f644659a780 (LWP 5034)):
[KCrash Handler]
#5  0x00007f6443b273d9 in raise () from /usr/lib/libc.so.6
#6  0x00007f6443b287d8 in abort () from /usr/lib/libc.so.6
#7  0x00007f64450d990f in qt_message_output(QtMsgType, char const*) () from /usr/lib/libQtCore.so.4
#8  0x00007f64450d9a99 in ?? () from /usr/lib/libQtCore.so.4
#9  0x00007f64450da2a4 in qFatal(char const*, ...) () from /usr/lib/libQtCore.so.4
#10 0x00007f642aa0778c in KateUndoManager::undo (this=0x1be4990) at /home/mssola/Projects/kde/kate/part/undo/kateundomanager.cpp:236
#11 0x00007f642a9dd9a9 in KateDocument::undo (this=0x1be4300) at /home/mssola/Projects/kde/kate/part/document/katedocument.cpp:1377
#12 0x00007f642aacc6f4 in KateViNormalMode::commandUndo (this=0x1ed0ae0) at /home/mssola/Projects/kde/kate/part/vimode/katevinormalmode.cpp:1516
#13 0x00007f642aae314c in KateViCommand::execute (this=0x1ee1f50) at /home/mssola/Projects/kde/kate/part/vimode/katevicommand.cpp:38
#14 0x00007f642aac85e6 in KateViNormalMode::executeCommand (this=0x1ed0ae0, cmd=0x1ee1f50) at /home/mssola/Projects/kde/kate/part/vimode/katevinormalmode.cpp:522
#15 0x00007f642aac81d0 in KateViNormalMode::handleKeypress (this=0x1ed0ae0, e=0x7fff5ccb1c10) at /home/mssola/Projects/kde/kate/part/vimode/katevinormalmode.cpp:436
#16 0x00007f642aab4077 in KateViInputModeManager::handleKeypress (this=0x1ed0a00, e=0x7fff5ccb1c10) at /home/mssola/Projects/kde/kate/part/vimode/kateviinputmodemanager.cpp:158
#17 0x00007f642aa94990 in KateViewInternal::keyPressEvent (this=0x1cdb0c0, e=0x7fff5ccb1c10) at /home/mssola/Projects/kde/kate/part/view/kateviewinternal.cpp:2339
#18 0x00007f642aa940df in KateViewInternal::eventFilter (this=0x1cdb0c0, obj=0x1cdb0c0, e=0x7fff5ccb1c10) at /home/mssola/Projects/kde/kate/part/view/kateviewinternal.cpp:2227
#19 0x00007f64451e4026 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () from /usr/lib/libQtCore.so.4
#20 0x00007f644436a10c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4
#21 0x00007f6444371941 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4
#22 0x00007f6445f9483a in KApplication::notify(QObject*, QEvent*) () from /usr/lib/libkdeui.so.5
#23 0x00007f64451e3ebd in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/libQtCore.so.4
#24 0x00007f642aa9d709 in QCoreApplication::sendEvent (receiver=0x1cdb0c0, event=0x7fff5ccb1c10) at /usr/include/qt4/QtCore/qcoreapplication.h:231
#25 0x00007f642aab4a20 in KateViInputModeManager::feedKeyPresses (this=0x1ed0a00, keyPresses=...) at /home/mssola/Projects/kde/kate/part/vimode/kateviinputmodemanager.cpp:258
#26 0x00007f642aab4fa8 in KateViInputModeManager::repeatLastChange (this=0x1ed0a00) at /home/mssola/Projects/kde/kate/part/vimode/kateviinputmodemanager.cpp:315
#27 0x00007f642aacd0b5 in KateViNormalMode::commandRepeatLastChange (this=0x1ed0ae0) at /home/mssola/Projects/kde/kate/part/vimode/katevinormalmode.cpp:1669
#28 0x00007f642aae314c in KateViCommand::execute (this=0x1ee2650) at /home/mssola/Projects/kde/kate/part/vimode/katevicommand.cpp:38
#29 0x00007f642aac85e6 in KateViNormalMode::executeCommand (this=0x1ed0ae0, cmd=0x1ee2650) at /home/mssola/Projects/kde/kate/part/vimode/katevinormalmode.cpp:522
#30 0x00007f642aac81d0 in KateViNormalMode::handleKeypress (this=0x1ed0ae0, e=0x7fff5ccb2b00) at /home/mssola/Projects/kde/kate/part/vimode/katevinormalmode.cpp:436
#31 0x00007f642aab4077 in KateViInputModeManager::handleKeypress (this=0x1ed0a00, e=0x7fff5ccb2b00) at /home/mssola/Projects/kde/kate/part/vimode/kateviinputmodemanager.cpp:158
#32 0x00007f642aa94990 in KateViewInternal::keyPressEvent (this=0x1cdb0c0, e=0x7fff5ccb2b00) at /home/mssola/Projects/kde/kate/part/view/kateviewinternal.cpp:2339
#33 0x00007f642aa940df in KateViewInternal::eventFilter (this=0x1cdb0c0, obj=0x1cdb0c0, e=0x7fff5ccb2b00) at /home/mssola/Projects/kde/kate/part/view/kateviewinternal.cpp:2227
#34 0x00007f64451e4026 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () from /usr/lib/libQtCore.so.4
#35 0x00007f644436a10c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4
#36 0x00007f6444371941 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/libQtGui.so.4
#37 0x00007f6445f9483a in KApplication::notify(QObject*, QEvent*) () from /usr/lib/libkdeui.so.5
#38 0x00007f64451e3ebd in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/libQtCore.so.4
#39 0x00007f642aa9d709 in QCoreApplication::sendEvent (receiver=0x1cdb0c0, event=0x7fff5ccb2b00) at /usr/include/qt4/QtCore/qcoreapplication.h:231
#40 0x00007f642aab4a20 in KateViInputModeManager::feedKeyPresses (this=0x1ed0a00, keyPresses=...) at /home/mssola/Projects/kde/kate/part/vimode/kateviinputmodemanager.cpp:258
#41 0x00007f642ab06d50 in KateViKeyMapper::playBackRejectedKeys (this=0x1eebc10) at /home/mssola/Projects/kde/kate/part/vimode/katevikeymapper.cpp:64
#42 0x00007f642ab070b5 in KateViKeyMapper::handleKeypress (this=0x1eebc10, key=...) at /home/mssola/Projects/kde/kate/part/vimode/katevikeymapper.cpp:123
#43 0x00007f642aab3f08 in KateViInputModeManager::handleKeypress (this=0x1ed0a00, e=0x7fff5ccb34f0) at /home/mssola/Projects/kde/kate/part/vimode/kateviinputmodemanager.cpp:136
#44 0x00007f642aa94990 in KateViewInternal::keyPressEvent (this=0x1cdb0c0, e=0x7fff5ccb34f0) at /home/mssola/Projects/kde/kate/part/view/kateviewinternal.cpp:2339
#45 0x00007f642aa940df in KateViewInternal::eventFilter (this=0x1cdb0c0, obj=0x1cdb0c0, e=0x7fff5ccb34f0) at /home/mssola/Projects/kde/kate/part/view/kateviewinternal.cpp:2227
#46 0x00007f64451e4026 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () from /usr/lib/libQtCore.so.4
Comment 5 Dominik Haumann 2013-12-01 15:04:09 UTC
This is a tricky one: KateUndoManager::undo() requires that no editStart/editEnd was called.
However, the vi mode does this in KateViNormalMode::executeCommand by calling startInsertMode() and then calling undo.

Is it possible to find a different solution here?
Comment 6 Simon St James 2013-12-01 15:20:54 UTC
Ah - looks like we need to fine-tune when we clear the "last command" logs - an "Undo" keypress is being added to them.
Comment 7 Michal Humpula 2013-12-01 16:25:52 UTC
This was actully added by fixing the repeat in visual mode:-D
Ok, let's be serious now. Here is the thing...

1. In normal mode, go to line 6 and select with Shift + V until line 8.
  * m_lastChange = ""
  * selected range in view as expected
2a. Indent the if statement with Shift + >
  * m_lastChange = "V↓↓>"
  * range still selected
2b. and undo this change afterwards.
  * m_lastChange = "V↓↓>"  -- "u" is not change cmd so everything ok
  * range still selected -- divergence from vim, which enables use of ">"
3. Indent the if statement with Shift + > again.
  * m_lastChange = "u>" -- which doesn't make much sense
  * range still selected
4. Press '.', => crash
  * will crash

So the questions are:
* Should kate copy the vim and just discard the selection? I'm guessing the crash would still be there, because it would still indent current line. So,...
* "u" should actualy clean the "m_currentChangeKeyEventsLog" after itself. What about "q" recording. Couldn't there be some conflict with this solution?
Comment 8 Michal Humpula 2013-12-01 16:37:53 UTC
damn it, make the mistake there:

2a. Indent the if statement with Shift + >
  * m_lastChange = "V↓↓>"
  * no selection -- as in vim
2b. and undo this change afterwards.
  * m_lastChange = "V↓↓>"  -- "u" is not change cmd so everything ok
  * range selected again -- divergence from vim, which enables use of ">"

Didn't noticed that undo is restoring selections too:)
Comment 9 Simon St James 2013-12-01 16:58:06 UTC
" range selected again -- divergence from vim, which enables use of ">""

Yep, this is a big factor in this bug, but though this behaviour differs from Vim and causes problems in this instance, I rather like it in general so would prefer that any solution preserves it.  I'll have a think :) There's a chance that we'll have to revert a portion of this and instead preserve the visual mode type (if any) along with storeLastChangeCommand(), and ensure we are in the correct visual mode (again, if any) when we replay it.  Which would be pretty ugly, but oh well :)
Comment 10 Michal Humpula 2013-12-01 17:16:41 UTC
tried adding m_viInputModeManager->clearCurrentChangeLog() into KateViNormalMode::commandUndo(). Seems like no tests are broken by this and the crash is gone. But... 

after hitting repeat "." the m_lastChange is ">" and nothing is selected now. So the result of it is like starting the indent normal mode command ">>". Which is not the user (at least me) expects to happen:-)

If the undo is supposed to return the last change only, not the selection, then I would agree that hitting "u"ndo should actually return to visual mode. In that case the m_lastChange would be again "V↓↓>" when the repeat "." would be pressed.
Comment 11 Michal Humpula 2013-12-04 21:33:18 UTC
Git commit 2ac36c4dc44ff61b6d56b536564f3f39a09ecdbe by Michal Humpula.
Committed on 01/12/2013 at 18:39.
Pushed by michalhumpula into branch 'master'.

vi-mode: fix crash in "Vj>u>." sequence

don't remember the "u" key after Undo command

REVIEW: 114248

M  +2    -0    part/vimode/katevinormalmode.cpp
M  +3    -0    tests/vimode_test.cpp

http://commits.kde.org/kate/2ac36c4dc44ff61b6d56b536564f3f39a09ecdbe