Bug 488624 - kdiff3 unusable due to crashing
Summary: kdiff3 unusable due to crashing
Status: RESOLVED FIXED
Alias: None
Product: kdiff3
Classification: Applications
Component: application (other bugs)
Version First Reported In: unspecified
Platform: Arch Linux Linux
: NOR crash
Target Milestone: ---
Assignee: michael
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-06-17 15:45 UTC by JATothrim
Modified: 2024-09-11 12:20 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments
Output of qtdiag tool (9.36 KB, text/x-log)
2024-06-17 15:45 UTC, JATothrim
Details

Note You need to log in before you can comment on or make changes to this bug.
Description JATothrim 2024-06-17 15:45:21 UTC
Created attachment 170571 [details]
Output of qtdiag tool

SUMMARY
kdiff3 somehow started to *always* crash on this system when given two or more files to compare. It's basically dead, and I'm using currently meld to go around this issue.

STEPS TO REPRODUCE
1. kdiff3 <relative path-to-file> <file>

OBSERVED RESULT
segfault, or dies to a thrown exception.

#0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#1  0x00007ffff5aa8eb3 in __pthread_kill_internal (threadid=<optimized out>, signo=6) at pthread_kill.c:78
#2  0x00007ffff5a50a30 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x00007ffff5a384c3 in __GI_abort () at abort.c:79
#4  0x00007ffff5c97b0c in __gnu_cxx::__verbose_terminate_handler () at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/vterminate.cc:95
#5  0x00007ffff5cadf1a in __cxxabiv1::__terminate (handler=<optimized out>) at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:48
#6  0x00007ffff5c9750a in std::terminate () at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:58
#7  0x00007ffff5cae1d6 in __cxxabiv1::__cxa_throw (obj=<optimized out>, tinfo=0x7ffff5e75dc0 <typeinfo for std::out_of_range>, dest=0x7ffff5cc4bc0 <std::out_of_range::~out_of_range()>)
    at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_throw.cc:98
#8  0x00007ffff5c9b403 in std::__throw_out_of_range_fmt (__fmt=__fmt@entry=0x555555696c28 "vector::_M_range_check: __n (which is %zu) >= this->size() (which is %zu)") at /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/functexcept.cc:101
#9  0x000055555558c77e in std::vector<LineData, std::allocator<LineData> >::_M_range_check (this=<optimized out>, __n=<optimized out>) at /usr/include/c++/14.1.1/bits/stl_vector.h:1160
#10 std::vector<LineData, std::allocator<LineData> >::at (this=<optimized out>, __n=<optimized out>) at /usr/include/c++/14.1.1/bits/stl_vector.h:1182
#11 Diff3Line::getLineData (this=<optimized out>, src=<optimized out>) at /usr/src/debug/kdiff3/kdiff3-1.11.1/src/diff.h:337
#12 0x0000555555624be8 in Diff3Line::getString (this=0x5555561d46b0, src=e_SrcSelector::A) at /usr/src/debug/kdiff3/kdiff3-1.11.1/src/diff.h:342
#13 Diff3LineList::findHistoryRange (this=<optimized out>, historyStart=..., bThreeFiles=false, range=...) at /usr/src/debug/kdiff3/kdiff3-1.11.1/src/diff.cpp:1626
#14 MergeResultWindow::slotMergeHistory (this=this@entry=0x5555557f2bb0) at /usr/src/debug/kdiff3/kdiff3-1.11.1/src/mergeresultwindow.cpp:1166
#15 0x00005555556276b0 in MergeResultWindow::merge (this=<optimized out>, bAutoSolve=true, defaultSelector=<optimized out>, bConflictsOnly=false, bWhiteSpaceOnly=<optimized out>)
    at /usr/src/debug/kdiff3/kdiff3-1.11.1/src/mergeresultwindow.cpp:379
#16 0x00005555555ded8e in MergeResultWindow::init (this=0x5555557f2bb0, pLineDataA=..., sizeA=..., pLineDataB=std::shared_ptr<std::vector<LineData, std::allocator<LineData> >> (use count 4, weak count 0) = {...}, sizeB=..., 
    pLineDataC=..., sizeC=..., pDiff3LineList=0x555555a45818, pTotalDiffStatus=0x555555a410f0, bAutoSolve=true) at /usr/src/debug/kdiff3/kdiff3-1.11.1/src/mergeresultwindow.cpp:132
#17 KDiff3App::mainInit (this=0x555555a453c0, pTotalDiffStatus=0x555555a410f0, inFlags=...) at /usr/src/debug/kdiff3/kdiff3-1.11.1/src/pdiff.cpp:380
#18 0x00005555555b48be in KDiff3App::doFileCompare (this=0x555555a453c0) at /usr/include/qt6/QtCore/qflags.h:74
#19 KDiff3App::completeInit (this=0x555555a453c0, fn1=..., fn2=..., fn3=...) at /usr/src/debug/kdiff3/kdiff3-1.11.1/src/kdiff3.cpp:493
#20 0x00005555555b7f34 in KDiff3Shell::KDiff3Shell (this=<optimized out>, fn1=..., fn2=..., fn3=..., this=<optimized out>, fn1=..., fn2=..., fn3=...) at /usr/src/debug/kdiff3/kdiff3-1.11.1/src/kdiff3_shell.cpp:39
#21 0x00005555555b81fc in operator() (__closure=0x555555944940) at /usr/src/debug/kdiff3/kdiff3-1.11.1/src/main.cpp:195
#22 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, main(qint32, char**)::<lambda()> >::call (f=..., arg=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:137
#23 QtPrivate::FunctorCallable<main(qint32, char**)::<lambda()> >::call<QtPrivate::List<>, void> (f=..., arg=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:345
#24 QtPrivate::QCallableObject<main(qint32, char**)::<lambda()>, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=<optimized out>, this_=0x555555944930, r=<optimized out>, 
    a=<optimized out>, ret=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:555
#25 0x00007ffff618c0ff in QObject::event (this=0x7fffffffde30, e=0x555555d07ef0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobject.cpp:1452
#26 0x00007ffff70fc55c in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x7fffffffde30, e=0x555555d07ef0) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qapplication.cpp:3287
#27 0x00007ffff6144e38 in QCoreApplication::notifyInternal2 (receiver=0x7fffffffde30, event=event@entry=0x555555d07ef0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1142
#28 0x00007ffff61451fb in QCoreApplication::sendEvent (receiver=<optimized out>, event=0x555555d07ef0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1583
#29 QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x5555556f4ba0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1940
#30 0x00007ffff63a460c in QCoreApplication::sendPostedEvents (receiver=0x0, event_type=0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1797
#31 postEventSourceDispatch (s=0x5555559ddd50) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:244
#32 0x00007ffff52e7a89 in g_main_dispatch (context=0x7fffe8000f00) at ../glib/glib/gmain.c:3344
#33 0x00007ffff53499b7 in g_main_context_dispatch_unlocked (context=0x7fffe8000f00) at ../glib/glib/gmain.c:4152
#34 g_main_context_iterate_unlocked.isra.0 (context=context@entry=0x7fffe8000f00, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/glib/gmain.c:4217
#35 0x00007ffff52e6f95 in g_main_context_iteration (context=0x7fffe8000f00, may_block=1) at ../glib/glib/gmain.c:4282
#36 0x00007ffff63a28dd in QEventDispatcherGlib::processEvents (this=0x55555597c390, flags=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:394
#37 0x00007ffff614f10e in QEventLoop::processEvents (this=0x7fffffffdd10, flags=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventloop.cpp:100
#38 QEventLoop::exec (this=0x7fffffffdd10, flags=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventloop.cpp:182
#39 0x00007ffff614945d in QCoreApplication::exec () at /usr/src/debug/qt6-base/qtbase/src/corelib/global/qflags.h:74
#40 0x00007ffff70f83fa in QApplication::exec () at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qapplication.cpp:2555
#41 0x000055555559d1de in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/kdiff3/kdiff3-1.11.1/src/main.cpp:198

EXPECTED RESULT
No crash, the diff/merge view works.

SOFTWARE/OS VERSIONS
kdiff3 --version reports: kdiff3 1.11.1

ADDITIONAL INFORMATION
Comment 1 JATothrim 2024-07-01 09:33:42 UTC
Got updated to 1.11.2 and I'm still experiencing the same bug. Just to note, this issue is slightly different from https://bugs.kde.org/show_bug.cgi?id=489494 and https://bugs.kde.org/show_bug.cgi?id=487338 in that the kdiff3 dies to thrown C++ exception from std::vector:

> terminate called after throwing an instance of 'std::out_of_range'
> what():  vector::_M_range_check: __n (which is 18446744073709551615) >= this->size() (which is 9976)

There is an unsigned integer undeflow or some signed/unsigned index funk somewhere. ;-) I would like to get this fixed asap, and I'm willing to build kdiff3 from the source to do this.
Comment 2 JATothrim 2024-07-02 10:59:07 UTC
I built kdiff3 in debug mode to able to step through the code in GDB, and diff.h:getLineData() has ran itself into an corner: it has to return a reference to something. The passed in argument is "e_SrcSelector::A" but "lineA" is invalid. So it keep going until "m_pDiffBufferInfo->getLineData(src)->at(lineC);" where lineC is also invalid and crashes thus crashes to "->at(-1);".

Only "lineB" is valid at the point of crash. (which isn't selected)
Comment 3 JATothrim 2024-08-16 17:41:31 UTC
I built kdiff3 today at git rev 9d2a70ea420778ef0a543d463c9ca71a29105b6c and this bug seems have been fixed!
Huge thanks for fixing this!

Apparently https://bugs.kde.org/show_bug.cgi?id=486782 was related, so I'm resolving this ticket.
Comment 4 JATothrim 2024-09-08 12:01:46 UTC
>:(
git version: 56034f129bb355418752ed89aa5166c216fbb161, built kdiff3 --version reports 1.11.70

(gdb) bt
#0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#1  0x00007ffff64a5463 in __pthread_kill_internal (threadid=<optimized out>, signo=6) at pthread_kill.c:78
#2  0x00007ffff644c120 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x00007ffff64334c3 in __GI_abort () at abort.c:79
#4  0x00007ffff5a97b2c in __gnu_cxx::__verbose_terminate_handler () at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/vterminate.cc:95
#5  0x00007ffff5aadffa in __cxxabiv1::__terminate (handler=<optimized out>) at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:48
#6  0x00007ffff5a9752a in std::terminate () at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_terminate.cc:58
#7  0x00007ffff5aae2b6 in __cxxabiv1::__cxa_throw (obj=<optimized out>, tinfo=0x7ffff5c76dc0 <typeinfo for std::out_of_range>, dest=0x7ffff5ac5810 <std::out_of_range::~out_of_range()>)
    at /usr/src/debug/gcc/gcc/libstdc++-v3/libsupc++/eh_throw.cc:98
#8  0x00007ffff5a9b423 in std::__throw_out_of_range_fmt (__fmt=0x55555579c8b0 "vector::_M_range_check: __n (which is %zu) >= this->size() (which is %zu)") at /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/functexcept.cc:101
#9  0x00005555556632d0 in std::vector<LineData, std::allocator<LineData> >::_M_range_check (this=0x555555eeab50, __n=18446744073709551615) at /usr/include/c++/14.2.1/bits/stl_vector.h:1160
#10 0x0000555555662163 in std::vector<LineData, std::allocator<LineData> >::at (this=0x555555eeab50, __n=18446744073709551615) at /usr/include/c++/14.2.1/bits/stl_vector.h:1182
#11 0x0000555555661626 in Diff3Line::getLineData (this=0x55555655ccc0, src=e_SrcSelector::A) at /usr/src/debug/kdiff3-git/kdiff3/src/diff.h:336
#12 0x0000555555661731 in Diff3Line::getString (this=0x55555655ccc0, src=e_SrcSelector::A) at /usr/src/debug/kdiff3-git/kdiff3/src/diff.h:341
#13 0x000055555565fdf0 in Diff3LineList::findHistoryRange (this=0x5555560052a8, historyStart=..., bThreeFiles=true, range=...) at /usr/src/debug/kdiff3-git/kdiff3/src/diff.cpp:1628
#14 0x00005555556862b1 in MergeResultWindow::slotMergeHistory (this=0x5555559ca080) at /usr/src/debug/kdiff3-git/kdiff3/src/mergeresultwindow.cpp:1149
#15 0x00005555556814d0 in MergeResultWindow::merge (this=0x5555559ca080, bAutoSolve=true, defaultSelector=e_SrcSelector::Min, bConflictsOnly=false, bWhiteSpaceOnly=false) at /usr/src/debug/kdiff3-git/kdiff3/src/mergeresultwindow.cpp:361
#16 0x000055555567d768 in MergeResultWindow::init (this=0x5555559ca080, pLineDataA=std::shared_ptr<std::vector<LineData, std::allocator<LineData> >> (use count 5, weak count 0) = {...}, sizeA=..., 
    pLineDataB=std::shared_ptr<std::vector<LineData, std::allocator<LineData> >> (use count 4, weak count 0) = {...}, sizeB=..., 
    pLineDataC=std::shared_ptr<std::vector<LineData, std::allocator<LineData> >> (use count 5, weak count 0) = {...}, sizeC=..., pDiff3LineList=0x5555560052a8, pTotalDiffStatus=0x555555eeaa30, bAutoSolve=true)
    at /usr/src/debug/kdiff3-git/kdiff3/src/mergeresultwindow.cpp:131
#17 0x000055555561429d in KDiff3App::mainInit (this=0x555556004f00, pTotalDiffStatus=0x555555eeaa30, inFlags=...) at /usr/src/debug/kdiff3-git/kdiff3/src/pdiff.cpp:389
#18 0x00005555555bbeff in KDiff3App::doFileCompare (this=0x555556004f00) at /usr/src/debug/kdiff3-git/kdiff3/src/kdiff3.cpp:610
#19 0x00005555555bc26f in KDiff3App::completeInit (this=0x555556004f00) at /usr/src/debug/kdiff3-git/kdiff3/src/kdiff3.cpp:647
#20 0x00005555555a95f1 in KDiff3Shell::KDiff3Shell (this=0x555555ac9520, fn1=..., fn2=..., fn3=..., __in_chrg=<optimized out>, __vtt_parm=<optimized out>) at /usr/src/debug/kdiff3-git/kdiff3/src/kdiff3_shell.cpp:39
#21 0x00005555555a32a9 in operator() (__closure=0x5555560908d0) at /usr/src/debug/kdiff3-git/kdiff3/src/main.cpp:192
#22 0x00005555555a5dff in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, main(qint32, char**)::<lambda()> >::call(struct {...} &, void **) (f=..., arg=0x555555dc21a8)
    at /usr/include/qt6/QtCore/qobjectdefs_impl.h:137
#23 0x00005555555a5dd1 in QtPrivate::FunctorCallable<main(qint32, char**)::<lambda()> >::call<QtPrivate::List<>, void>(struct {...} &, void *, void **) (f=..., arg=0x555555dc21a8) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:345
#24 0x00005555555a5d92 in QtPrivate::QCallableObject<main(qint32, char**)::<lambda()>, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=1, this_=0x5555560908c0, r=0x7fffffffdb90, 
    a=0x555555dc21a8, ret=0x0) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:555
#25 0x00007ffff5f8d89f in QObject::event (this=0x7fffffffdb90, e=0x555555dc2160) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobject.cpp:1452
#26 0x00007ffff70fc8cc in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x7fffffffdb90, e=0x555555dc2160) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qapplication.cpp:3287
#27 0x00007ffff5f45aa8 in QCoreApplication::notifyInternal2 (receiver=0x7fffffffdb90, event=event@entry=0x555555dc2160) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1142
#28 0x00007ffff5f45e6b in QCoreApplication::sendEvent (receiver=<optimized out>, event=0x555555dc2160) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1583
#29 QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x5555558d1ba0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1940
#30 0x00007ffff61aa00c in QCoreApplication::sendPostedEvents (receiver=0x0, event_type=0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1797
#31 postEventSourceDispatch (s=0x555555941700) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:244
#32 0x00007ffff5511299 in g_main_dispatch (context=0x7fffe8000f00) at ../glib/glib/gmain.c:3344
#33 0x00007ffff5573ec7 in g_main_context_dispatch_unlocked (context=0x7fffe8000f00) at ../glib/glib/gmain.c:4152
#34 g_main_context_iterate_unlocked.isra.0 (context=context@entry=0x7fffe8000f00, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/glib/gmain.c:4217
#35 0x00007ffff5510795 in g_main_context_iteration (context=0x7fffe8000f00, may_block=1) at ../glib/glib/gmain.c:4282
#36 0x00007ffff61a82bd in QEventDispatcherGlib::processEvents (this=0x555555a96e70, flags=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:394
#37 0x00007ffff5f4ff66 in QEventLoop::processEvents (this=0x7fffffffdaa0, flags=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventloop.cpp:100
#38 QEventLoop::exec (this=0x7fffffffdaa0, flags=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventloop.cpp:182
#39 0x00007ffff5f4a11d in QCoreApplication::exec () at /usr/src/debug/qt6-base/qtbase/src/corelib/global/qflags.h:74
#40 0x00007ffff70f86aa in QApplication::exec () at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qapplication.cpp:2555
#41 0x00005555555a4d57 in main (argc=13, argv=0x7fffffffdf18) at /usr/src/debug/kdiff3-git/kdiff3/src/main.cpp:195
(gdb) frame 11
#11 0x0000555555661626 in Diff3Line::getLineData (this=0x55555655ccc0, src=e_SrcSelector::A) at /usr/src/debug/kdiff3-git/kdiff3/src/diff.h:336
336	        return m_pDiffBufferInfo->getLineData(src)->at(lineC);
(gdb) p lineC
$3 = {static invalid = -1, mLineNumber = {m_t = -1}}
(gdb) info args
this = 0x55555655ccc0
src = e_SrcSelector::A

I rejoiced too early. Reeves (or who is the responsible maintainer), seriously, by all respect how this is not staying fixed? How/why did this break/regress again?

The kdiff3 dies to ->at(size_t(-1)) which will throw std::out_of_range because of accessing at index 18446744073709551615, and this bug is reproduced by simply doing a three-way merge.
Comment 5 michael 2024-09-08 16:35:01 UTC
Going the address this directly sorry for the delay unfortunately I find myself as the only one doing work with this code. My attention has been else where lately. In particular dealing with the odd error on startup that I managed to reproduce. So far this hasn't happened for me but looks like an issue with  Diff3Line::getString itself. Look at it now.
Comment 6 JATothrim 2024-09-08 19:10:11 UTC
> Going the address this directly sorry for the delay unfortunately I find myself as the only one doing work with this code. My attention has been else where lately. In particular dealing with the odd error on startup that I managed to reproduce. So far this hasn't happened for me but looks like an issue with  Diff3Line::getString itself. Look at it now.

No need for sorry, I understand. I see you as one of the important people as best described by xkcd 2347. kdiff3 somehow has ended up as the *only* usable+sane three-way merge tool with GUI) for me, so I was going to give you code on this time, rather than just complaining. I wrote an fix-up commit to correct the bug. Will take a day to set-up to publish a fork with the commit on gitlab.

Ah, I see you already did a fix on master. I would slightly reconsider this approach:
(gdb) frame 13
(gdb) p range
$1 = (HistoryRange &) @0x7fffffffcc10: {
  start = {lineA = {static invalid = -1, mLineNumber = {m_t = -1}}, lineB = {static invalid = -1, mLineNumber = {m_t = 61}}, lineC = {static invalid = -1, mLineNumber = {m_t = -1}}, bAEqC = false, bBEqC = false, bAEqB = false, bWhiteLineA = true, bWhiteLineB = false, bWhiteLineC = true, pFineAB = std::shared_ptr<const DiffList> (empty) = {get() = 0x0}, pFineBC = std::shared_ptr<const DiffList> (empty) = {get() = 0x0}, pFineCA = std::shared_ptr<const DiffList> (empty) = {get() = 0x0}, mLinesNeededForDisplay = 1, mSumLinesNeededForDisplay = 0}, end = non-dereferenceable iterator for std::list, startIdx = 64, endIdx = -1}

My fix was just going to select any of lineA, lineB or lineC (prioritizing nearest lineC as in original code) after the the exact selection would have failed. Unless it's possible that all *three* selector are invalid at same, yours solution would be still required.
Comment 7 michael 2024-09-09 02:14:22 UTC
Have a patch attempt in master.. That may help with the this. If so it can be back ported to stable.
Comment 8 JATothrim 2024-09-11 07:18:41 UTC
> Have a patch attempt in master.. That may help with the this. If so it can be back ported to stable.

Tested, the fix works! :)

However, mentioned in https://invent.kde.org/sdk/kdiff3/-/merge_requests/61 that https://invent.kde.org/sdk/kdiff3/-/commit/2cc13f8b03ef3d070a7be2b2ffd8d5b916a1fd6f fix alone isn't enough, and for stable the 000dd8cdf365098b11e9f733c0313bfb42b7d52a is also needed (or that reverted the part is not introduced in stable).

I published the extra code I had written top of 2cc13f8b03ef3d070a7be2b2ffd8d5b916a1fd6f
However, I didn't make a merge request out of it, as I'm unsure if it would be useful:
Commit https://invent.kde.org/jatothrim/kdiff3/-/commit/0ca09b38c2a38e290317655cf69ce414f88897ef  since it affects the merge output...

Anyway, thanks for your time and quick response.
Comment 9 JATothrim 2024-09-11 12:20:00 UTC
> I published the extra code I had written top of 2cc13f8b03ef3d070a7be2b2ffd8d5b916a1fd6f
> However, I didn't make a merge request out of it, as I'm unsure if it would be useful
> https://invent.kde.org/jatothrim/kdiff3/-/commit/0ca09b38c2a38e290317655cf69ce414f88897ef

I apparently just hit a situation where this commit could be useful (but I need to do a bit of development for this). On a three-way merge, with the current fixes in master, I cannot select a change, as kdiff3 now insist there is only white-space difference on line selection, which is not right.  The three-way merge is thus un-resolvable.

Well since at least the crashes are now fixed, so I think I can close this bug ticket despite of this new issue...