Emergency-dialog options

Pavel Sanda sanda at lyx.org
Thu Mar 25 10:35:44 UTC 2021


On Sun, Mar 14, 2021 at 09:40:38PM +0100, Pavel Sanda wrote:
> we have two 2.4 milestoned bugs:
> #11253 - requesting option of opening both side by side.
> #4658 - requesting option of running comparison between original and emergency copy
> 
> No one is actually sure about the best way how to fix the dialog.
> I see these options: 
> a) fix #11253 only
> b) fix #4658 only
> c) offer both ways in the dialog
> d) do #4658, but show only the resulting difference without visually opening
>    original and emergency.
> Or perhaps different scenario.
> 
> I think that the only sane thing to do after opening both is to run comparison
> and check. Also once both emergency and original are loaded you can't as easily
> remove the emergency or replace the orignal. So I tend to choose the option d).
> What others think?

Attached is my attempt to address those bugs. I won't commit because there is
problem I currently do not know how to address.
It adds new button for displaying diff only and runs compare machinery if selected.

There is however some memory corruption which is causing crash in ~20% of trials 
and sometimes I can see some garbage in Environment combo box.

If it crashes the backtrace always leads to:

Thread 5 "lyx::Compare" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffea115700 (LWP 13732)]
0x00005555582918a0 in ?? ()
(gdb) bt
#0  0x00005555582918a0 in ?? ()
#1  0x0000555556338523 in lyx::CursorSlice::nargs (this=0x7fffe0039ed0) at CursorSlice.h:92
#2  0x000055555642739e in lyx::CursorSlice::lastidx (this=0x7fffe0039ed0) at CursorSlice.h:70
#3  0x0000555556437e10 in lyx::DocIterator::lastidx (this=0x7fffea114b20) at DocIterator.cpp:259
#4  0x00005555564386cf in lyx::DocIterator::backwardPos (this=0x7fffea114b20) at DocIterator.cpp:453
#5  0x00005555562de6fd in lyx::DocRange::DocRange (this=0x7fffea114ad0, buf=0x5555580a1040) at Compare.cpp:71
#6  0x00005555562de9ce in lyx::DocRangePair::DocRangePair (this=0x7fffea114ad0, o_buf=0x5555580a1040,
    n_buf=0x555558220280) at Compare.cpp:150
#7  0x00005555562dc52f in lyx::Compare::Impl::diff (this=0x55555822b4a0, new_buf=0x555558220280,
    old_buf=0x5555580a1040, dest_buf=0x5555582dc8b0) at Compare.cpp:724
#8  0x00005555562dacb6 in lyx::Compare::doCompare (this=0x55555825aa60) at Compare.cpp:420
#9  0x00005555562dab3a in lyx::Compare::run (this=0x55555825aa60) at Compare.cpp:403


I can see two possible reasons: 
1. Compare is using threads and there is some resource conflict (like writing to LYXERR or whatever)
2. Loading the first buffer is not completely finished when launching compare
   which itself will load another document.

The problem with reproducibility leads me to think towards 1; I also looked at
the various pathways how we load the document and only nonessential stuff (like
connections to workarea) is missing before loading the second emergency buffer.
On the other hand the crash backtraces is always the same and seems that cursorslice::inset_ is wrong
so this recursive document load might indeed mi(/e)ss something.

Other option would be to rewrite the machinery so emergency check is not tried in special cases and we can
load both documents sequentially. That would be more complex change and I am running out of time now.

So unless there is some other bright idea I tend to delete 2.4 milestone for #11253.

Pavel
-------------- next part --------------
diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index fdce444aef..e243453015 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -4694,7 +4694,7 @@ Buffer::ReadStatus Buffer::loadEmergency()
 		"%1$s exists.\n\nRecover emergency save?"), file);
 
 	int const load_emerg = Alert::prompt(_("Load emergency save?"), text,
-		0, 2, _("&Recover"), _("&Load Original"), _("&Cancel"));
+		0, 3, _("&Recover"), _("&Load Original"), _("&Only show difference"), _("&Cancel"));
 
 	switch (load_emerg)
 	{
@@ -4769,6 +4769,16 @@ Buffer::ReadStatus Buffer::loadEmergency()
 		return ReadOriginal;
 	}
 
+	case 2: {
+		string f1 = d->filename.absFileName();
+		string f2 = emergencyFile.absFileName();
+		if (loadThisLyXFile(d->filename) != ReadSuccess)
+			return ReadCancel;
+		string par = "compare run " + quoteName(f1) + " " + quoteName(f2);
+		LYXERR(Debug::FILES, par << "\n");
+		lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, par));
+		return ReadCancel; //Release the buffer immediately
+	}
 	default:
 		break;
 	}


More information about the lyx-devel mailing list