On 12/30/2016 11:05 AM, Jean-Marc Lasgouttes wrote:
> Le 29/12/2016 à 07:21, Guillaume Munch a écrit :
>> Le 27/12/2016 à 23:11, Scott Kostyshak a écrit :
>>> On Tue, May 31, 2016 at 01:15:38AM +0200, Guillaume Munch wrote:
>>>> commit 1cc14a31ca8320d881b674f93c34a09cf1666cca
>>>> Author: Guillaume Munch <g...@lyx.org>
>>>> Date:   Mon May 30 21:42:08 2016 +0100
>>>>
>>>>     TocWidget: fix an erroneous collapse and optimise updates based
>>>> on profiling
>>>>
>>>>     TocModels::reset() in GuiView::structureChanged() collapses the
>>>> TocWidget, and
>>>>     therefore requires an update right after, which was missing.
>>>>
>>>>     In fact, profiling TocWidget::updateView() shows that delaying
>>>> the update is
>>>>     good only for fast keypresses (essentially movement). It costs 5%
>>>> of a
>>>>     char-forward operation in a document with approx. 100 table of
>>>> contents
>>>>     items. The update optimisation has been rewritten to take this
>>>> data into
>>>>     account.
>>>
>>> A git bisect suggests this causes a SIGSEGV. To reproduce:
>>>
>>> 1. open the attached file
>>> 2. open the outline pane
>>> 3. put the cursor just to the left of "Hello" (but inside the caption
>>> inset)
>>> 4. "Save As" to a new filename.
>>>
>>> Can you reproduce?
>>>
>>> Backtrace is attached.
>>>
>>
>> Hi,
>>
>> The root of the issue is in Buffer::reload() called during "Save As".
>> After loadLyXFile() there, all the insets have been deleted, and
>> therefore the Inset pointer
>> GuiView::documentBufferView()->cursor().inset() is dangling. Immediately
>> after loadLyXFile(), reload() calls updateBuffer() from your backtrace
>> which then crashes.
>
> In general this is when we add a cursor.fixIfBroken() somewhere.

Yes, that would simplify things.

>> The attached patch fixes this crash, but I find very unsatisfactory to
>> have to update the cursors by hand like this.
>
> What's with all the indirections? Updating directly one cursor seems
> more straightforward.

The issue seems to be getting a cursor in the first place, since this
has to be done from Buffer. One option would be to pass a Cursor (or
optional pointer to a Cursor) to Buffer::reload(). Then that can be
fixed after the reload is successful. How's that sound? Otherwise, we do
have to go via the gui_ pointer in Buffer, which is what leads to all
the redirection.

Richard

Reply via email to