#667 Crash after changing document in the background and asking TeXstudio to reload

None
closed
nobody
None
7
2014-12-25
2013-01-02
No

Well, this happens again and again. I use Git as version control system, often with operations such as stash and rebase which rewrite (replace?) files in the working copy. If a file that is opened in TeXstudio is rewritten by Git, TeXstudio asks if it should reload the file. I click "Yes", TeXstudio crashes. Lucky me, I run it in gdb ;-)

(NB: I have posted this before. I would really adore if TeXstudio would silently load the file if all changes in the editor have been saved, and record this as one big "replace all file contents" action in the Undo stack -- just like if I chose "Select all" from the "Edit" (?) menu and pasted the new file contents into the editor. Perhaps as an expert option. Just like Eclipse and Visual Studio and many many other editors. I don't remember the outcome of that discussion...)

Here is the backtrace (Ubuntu 12.10 amd64, TeXStudio SVN 3620), please let me know if you want more information, more backtraces or a reproducible example:

/home/.../Filename.tex modified.
[Thread 0x7fff98ccb700 (LWP 23096) exited]
[Thread 0x7fff9a4ce700 (LWP 23097) exited]
[New Thread 0x7fff9a4ce700 (LWP 24790)]
[New Thread 0x7fff98ccb700 (LWP 24791)]
No document for entry: 0x2012c20
   level: 7602144
   type: 1
   line nr: 96

Program received signal SIGSEGV, Segmentation fault.
0x000000000044a50d in QBasicAtomicInt::ref (this=0x18) at /usr/include/qt4/QtCore/qatomic_x86_64.h:121
121                  : "memory");
(gdb) bt
#0  0x000000000044a50d in QBasicAtomicInt::ref (this=0x18) at /usr/include/qt4/QtCore/qatomic_x86_64.h:121
#1  0x000000000044a596 in QString::QString (this=0x7fffffffbb50, other=...) at /usr/include/qt4/QtCore/qstring.h:726
#2  0x00000000006771f4 in StructureEntry::debugPrint (this=0x2012c20, message=0x93b81a "No document for entry:")
    at latexdocument.cpp:1160
#3  0x0000000000678b73 in LatexDocumentsModel::parent (this=0x105e300, index=...) at latexdocument.cpp:1355
#4  0x00007ffff5d169b2 in parent (this=<optimized out>) at kernel/qabstractitemmodel.h:393
#5  QAbstractItemModelPrivate::rowsAboutToBeInserted (this=this@entry=0x105e370, parent=..., first=first@entry=0, 
    last=last@entry=0) at kernel/qabstractitemmodel.cpp:575
#6  0x00007ffff5d17dc6 in QAbstractItemModel::beginInsertRows (this=0x105e300, parent=..., first=0, last=0)
    at kernel/qabstractitemmodel.cpp:2417
#7  0x000000000067936d in LatexDocumentsModel::addElement (this=0x105e300, se=0x2588500, row=0) at latexdocument.cpp:1469
#8  0x000000000087d1fd in LatexDocumentsModel::qt_static_metacall (_o=0x105e300, _c=QMetaObject::InvokeMetaMethod, _id=5, 
    _a=0x7fffffffbed0) at .moc/moc_latexdocument.cpp:414
#9  0x00007ffff5d35f5f in QMetaObject::activate (sender=0x238ddf0, m=<optimized out>, local_signal_index=<optimized out>, 
    argv=0x7fffffffbed0) at kernel/qobject.cpp:3547
#10 0x000000000087ceb6 in LatexDocument::addElement (this=0x238ddf0, _t1=0x2588500, _t2=0) at .moc/moc_latexdocument.cpp:311
#11 0x000000000067e015 in LatexDocument::insertElementWithSignal (this=0x238ddf0, parent=0x2588500, pos=0, se=0x2670ea0)
    at latexdocument.cpp:1996
#12 0x0000000000672f8d in LatexDocument::patchStructure (this=0x238ddf0, linenr=0, count=145) at latexdocument.cpp:771
#13 0x0000000000490c15 in Texmaker::fileReloaded (this=0x105a000) at texmaker.cpp:1757
#14 0x000000000086fb1b in Texmaker::qt_static_metacall (_o=0x105a000, _c=QMetaObject::InvokeMetaMethod, _id=290, 
    _a=0x7fffffffcb00) at .moc/moc_texmaker.cpp:1027
---Type <return> to continue, or q <return> to quit---
#15 0x00007ffff5d35f5f in QMetaObject::activate (sender=0x27fdee0, m=<optimized out>, local_signal_index=<optimized out>, 
    argv=0x0) at kernel/qobject.cpp:3547
#16 0x000000000088d701 in QEditor::fileReloaded (this=0x27fdee0) at .moc/moc_qeditor.cpp:579
#17 0x0000000000740506 in QEditor::fileChanged (this=0x27fdee0, file=...) at qcodeedit/lib/qeditor.cpp:1172
#18 0x000000000088c805 in QEditor::qt_static_metacall (_o=0x27fdee0, _c=QMetaObject::InvokeMetaMethod, _id=91, 
    _a=0x7fffffffce20) at .moc/moc_qeditor.cpp:375
#19 0x00007ffff5d28987 in QMetaMethod::invoke (this=this@entry=0x7fffffffcf90, object=object@entry=0x27fdee0, 
    connectionType=Qt::DirectConnection, connectionType@entry=Qt::AutoConnection, returnValue=..., val0=..., val1=..., 
    val2=..., val3=..., val4=..., val5=..., val6=..., val7=..., val8=..., val9=...) at kernel/qmetaobject.cpp:1664
#20 0x00007ffff5d2ad5c in QMetaObject::invokeMethod (obj=0x27fdee0, member=<optimized out>, type=Qt::AutoConnection, ret=..., 
    val0=..., val1=..., val2=..., val3=..., val4=..., val5=..., val6=..., val7=..., val8=..., val9=...)
    at kernel/qmetaobject.cpp:1179
#21 0x00000000006f4364 in QMetaObject::invokeMethod (obj=0x27fdee0, member=0x9487f6 "fileChanged", val0=..., val1=..., 
    val2=..., val3=..., val4=..., val5=..., val6=..., val7=..., val8=..., val9=...) at /usr/include/qt4/QtCore/qobjectdefs.h:434
#22 0x000000000076b57c in QReliableFileWatch::timerEvent (this=0x1d24df0, e=0x7fffffffdaf0)
    at qcodeedit/lib/qreliablefilewatch.cpp:147
#23 0x00007ffff5d3526c in QObject::event (this=0x1d24df0, e=<optimized out>) at kernel/qobject.cpp:1157
#24 0x00007ffff6583e9c in QApplicationPrivate::notify_helper (this=this@entry=0xe55ec0, receiver=receiver@entry=0x1d24df0, 
    e=e@entry=0x7fffffffdaf0) at kernel/qapplication.cpp:4562
#25 0x00007ffff658830a in QApplication::notify (this=0x7fffffffdf00, receiver=0x1d24df0, e=0x7fffffffdaf0)
    at kernel/qapplication.cpp:4423
#26 0x00007ffff5d2056e in QCoreApplication::notifyInternal (this=0x7fffffffdf00, receiver=0x1d24df0, event=0x7fffffffdaf0)
---Type <return> to continue, or q <return> to quit---
    at kernel/qcoreapplication.cpp:915
#27 0x00007ffff5d51462 in sendEvent (event=0x7fffffffdaf0, receiver=<optimized out>)
    at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:231
#28 QTimerInfoList::activateTimers (this=0xe5b150) at kernel/qeventdispatcher_unix.cpp:611
#29 0x00007ffff5d4e584 in timerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:186
#30 timerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:180
#31 0x00007ffff5d4e5a1 in idleTimerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:233
#32 0x00007ffff4266ab5 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#33 0x00007ffff4266de8 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#34 0x00007ffff4266ea4 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#35 0x00007ffff5d4ebf6 in QEventDispatcherGlib::processEvents (this=0xe52960, flags=...) at kernel/qeventdispatcher_glib.cpp:424
#36 0x00007ffff6628c1e in QGuiEventDispatcherGlib::processEvents (this=<optimized out>, flags=...)
    at kernel/qguieventdispatcher_glib.cpp:204
#37 0x00007ffff5d1f2bf in QEventLoop::processEvents (this=this@entry=0x7fffffffdd70, flags=...) at kernel/qeventloop.cpp:149
#38 0x00007ffff5d1f548 in QEventLoop::exec (this=0x7fffffffdd70, flags=...) at kernel/qeventloop.cpp:204
#39 0x00007ffff5d24708 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1187
#40 0x000000000044d708 in main (argc=1, argv=0x7fffffffe038) at main.cpp:178

Discussion

  • Benito van der Zander

    TeXstudio crashes. Lucky me, I run it in |gdb| ;-)
    Actually txs has a crash handler that is supposed to catch these kind
    of crashes.

    (NB: I have posted this before. I would really adore if TeXstudio
    would silently load the file if all changes in the editor have been
    saved, and record this as one big "replace all file contents" action
    in the Undo stack -- just like if I chose "Select all" from the "Edit"
    (?) menu and pasted the new file contents into the editor. Perhaps as
    an expert option. Just like Eclipse and Visual Studio and many many
    other editors. I don't remember the outcome of that discussion...)

    That would be a little bit tricky with the line modification status.
    Clear all? Make all green?

    or a reproducible example:

    That's always good to have

    StructureEntry::debugPrint (this=0x2012c20, message=0x93b81a "No document for entry:")

    So it might be caused by the same issue that causes #666

    (edit: reformated quotes)

     
    Last edit: Tim Hoffmann 2013-01-02
    • Tim Hoffmann

      Tim Hoffmann - 2013-01-02

      That would be a little bit tricky with the line modification status.
      Clear all? Make all green?

      From the strict editor logic it would be all green because you replaced all. But likely you replaced most of the text with identical text. If we wanted to be totally correct on the line change state, we'd have to run a diff to determine the lines which have really changed. However, I'd clear all markers in this case. Then the change state refers to the last version on disk (which IS a semantic change). But I'd be willing to accept this. In case of all green the markers become useless also for further changes.

       
  • Tim Hoffmann

    Tim Hoffmann - 2013-01-02

    The above can be reproduced by

    // load first document (as master, e.g. by restore session)
    Create StructureEntry(0x1c603678) LatexDocument(0x1a6b7480) SE_ROOT
    Create StructureEntry(0x1c603760) LatexDocument(0x1a6b7480) SE_OVERVIEW
    Create StructureEntry(0x1c6037b0) LatexDocument(0x1a6b7480) SE_OVERVIEW
    Create StructureEntry(0x1c603800) LatexDocument(0x1a6b7480) SE_OVERVIEW
    Create StructureEntry(0x1c603850) LatexDocument(0x1a6b7480) SE_OVERVIEW
    Create StructureEntry(0x1c6038a0) LatexDocument(0x1a6b7480) SE_OVERVIEW
    Create LatexEditorView(0x1c603a28) ""
    // load a second document
    Create StructureEntry(0x1c4b86c0) LatexDocument(0x1a841348) SE_ROOT
    Create StructureEntry(0x1a768d40) LatexDocument(0x1a841348) SE_OVERVIEW
    Create StructureEntry(0x1a7e4ce8) LatexDocument(0x1a841348) SE_OVERVIEW
    Create StructureEntry(0x187b2228) LatexDocument(0x1a841348) SE_OVERVIEW
    Create StructureEntry(0x1cb5d580) LatexDocument(0x1a841348) SE_OVERVIEW
    Create StructureEntry(0x1a78d328) LatexDocument(0x1a841348) SE_OVERVIEW
    Create LatexEditorView(0x1a76fe98) ""
    // externally modify the first document:
    C:/Users/Tim/Desktop/test.tex modified.
    Del StructureEntry(0x1c603760)
    Del StructureEntry(0x1c6037b0)
    Del StructureEntry(0x1c603800)
    Del StructureEntry(0x1c603850)
    Del StructureEntry(0x1c6038a0)
    Del StructureEntry(0x1c603678)
    Create StructureEntry(0x1a7aed98) LatexDocument(0x1a6b7480) SE_ROOT
    Create StructureEntry(0x1a764790) LatexDocument(0x1a6b7480) SE_OVERVIEW
    Create StructureEntry(0x1a764da0) LatexDocument(0x1a6b7480) SE_OVERVIEW
    Create StructureEntry(0x1cbcde08) LatexDocument(0x1a6b7480) SE_OVERVIEW
    Create StructureEntry(0x1a75c630) LatexDocument(0x1a6b7480) SE_OVERVIEW
    Create StructureEntry(0x1a780c78) LatexDocument(0x1a6b7480) SE_OVERVIEW
    // again modify the first document:
    C:/Users/Tim/Desktop/test.tex modified.
    Del StructureEntry(0x1a764790)
    Del StructureEntry(0x1a764da0)
    Del StructureEntry(0x1cbcde08)
    Del StructureEntry(0x1a75c630)
    Del StructureEntry(0x1a780c78)
    No document for entry: 0x1c603678
    level: 0
    type: 116027784
    line nr: -1163067392
    

    So we have someone still pointing to the original root StructureEntry(0x1c603678), which was deleted due to the first modification.

     
  • Kirill Müller

    Kirill Müller - 2013-01-02

    Thank you for your feedback.

    Tim: Can you add that to the test suite?

    I'd be perfectly fine with clearing the modification status upon external change. Perhaps the reload behavior and the marker update are two separate issues: Couldn't you implement smooth reload with a "simple" marker-resetting strategy first, and add a "smart" marker update later (perhaps with a new color signalizing the external change)? I could add two new entries to the issue tracker.

     
  • Tim Hoffmann

    Tim Hoffmann - 2013-01-02

    First we have to track down the crash issue, then we can talk on the modality of reloading.

    I just noted that my above procedure leading to a crash has a slightly different call stack than Kirill's:

    0   QBasicAtomicInt::ref    qatomic_i386.h  120 0x82a588    
    1   QString::QString    qstring.h   726 0x8fa414    
    2   StructureEntry::debugPrint  latexdocument.cpp   1162    0x5c3272    
    3   LatexDocumentsModel::parent latexdocument.cpp   1359    0x5c50ad    
    4   QModelIndex::parent qabstractitemmodel.h    393 0x69e8ef8e  
    5   QAbstractItemModelPrivate::rowsAboutToBeRemoved qabstractitemmodel.cpp  726 0x69dcbf52  
    6   QAbstractItemModel::beginRemoveRows qabstractitemmodel.cpp  2471    0x69dceb8a  
    7   LatexDocumentsModel::removeElement  latexdocument.cpp   1462    0x5c5745    
    8   LatexDocumentsModel::qt_static_metacall moc_latexdocument.cpp   412 0x77d7b1    
    9   QMetaObject::activate   qobject.cpp 3547    0x69de9baf  
    10  LatexDocument::removeElement    moc_latexdocument.cpp   298 0x77d472    
    11  LatexDocument::clearStructure   latexdocument.cpp   156 0x5b9ca4    
    12  Texmaker::fileAutoReloading texmaker.cpp    1744    0x45055b    
    13  Texmaker::qt_static_metacall    moc_texmaker.cpp    1029    0x7715f3    
    14  QMetaObject::activate   qobject.cpp 3547    0x69de9baf  
    15  QEditor::fileAutoReloading  moc_qeditor.cpp 592 0x78a7f4    
    16  QEditor::fileChanged    qeditor.cpp 1169    0x65d300    
    17  QEditor::qt_static_metacall moc_qeditor.cpp 375 0x789b63    
    18  QMetaMethod::invoke qmetaobject.cpp 1664    0x69dda994  
    19  QMetaObject::invokeMethod   qmetaobject.cpp 1179    0x69dd9e6b  
    20  QMetaObject::invokeMethod   qobjectdefs.h   434 0x80f082    
    ... <Mehr>              
    

    In both cases the problem arises in LatexDocumentsModel::parent ( const QModelIndex & index )

    const StructureEntry* entry = (StructureEntry*) index.internalPointer();
    

    It seems, the internalPointer() is not updated on reload. So after the first reload it is invalid and therefore crashes on the second reload.

     
  • Benito van der Zander

    Perhaps the removeElement call from clearStructure is not working correctly. It should remove the element from the structure view on the first reload, and then there were no reference anymore...

    But it does not crash for me (with qt4.8, linux) . edit: actually it does crash if it is opened with restore session, instead opened manually

     
    Last edit: Benito van der Zander 2013-01-03
  • Benito van der Zander

    Seems like the view gets the index again when endRemoveRows is called.

    Adding baseStructure = 0; directly after delete baseStructure; and
    before removeElementFinished fix the use-after-free. (but then comes an
    assert failure checking for NULL entries)

    Was there a specific reason the baseStructure entry is deleted at all?

     
    • Tim Hoffmann

      Tim Hoffmann - 2013-01-03

      Was there a specific reason the baseStructure entry is deleted at all?

      I'm not familiar with this part of the code.

      More general, is there a need for clearStructure() at all? We could adopt Kirill's idea of just replacing all the text (and resetting the save state and the line modifications). It's likely a bit worse in terms of performance, but it updates the structure without explicit modifications. This should also solve the issue of the lost undo/redo stack on reload.

       
  • Benito van der Zander

    More general, is there a need for clearStructure() at all? We could
    adopt Kirill's idea of just replacing all the text (and resetting the
    save state and the line modifications)
    I think it is also used in other places

     
  • Benito van der Zander

    removed the deletion, should not crash anymore...

     
  • Tim Hoffmann

    Tim Hoffmann - 2013-01-06
    • status: open --> closed
    • milestone: -->
     

Log in to post a comment.