Bug 487338

Summary: Possible regression: Floating point exception
Product: [Applications] kdiff3 Reporter: Mat <kde>
Component: applicationAssignee: michael <reeves.87>
Status: RESOLVED FIXED    
Severity: critical CC: lari, mapper74, mokazemi, sam, sergio.callegari
Priority: NOR    
Version: 1.11.1   
Target Milestone: ---   
Platform: Homebrew (macOS)   
OS: macOS   
Latest Commit: Version Fixed In: 1.11.3
Sentry Crash Report:

Description Mat 2024-05-21 19:27:13 UTC
SUMMARY


STEPS TO REPRODUCE
1.  Install kdiff3 1.11.1 on MacOS using brew
2. Launch kdiff3 using git mergetool (it launches with --auto --L1 --L2 --L3 -o and redirects stderr to stdout and stdout to /dev/null

Example command line:
/Applications/kdiff3.app/Contents/MacOS/kdiff3 --auto --L1 'path/to/MyFile.java (Base)' --L2 'path/to/MyFile.java (Local)' --L3 'path/to/MyFile.java (Remote)' -o path/to/MyFile.java ./path/to/MyFile_BASE_31578.java ./path/to/MyFile_LOCAL_31578.java ./path/to/MyFile_REMOTE_31578.java

OBSERVED RESULT
Floating point exception: 8

EXPECTED RESULT
Diff shown

SOFTWARE/OS VERSIONS
macOS: 14.4.1
KDE Frameworks Version 6.2.0
Qt Version 6.7.0 (built against 6.7.0)

ADDITIONAL INFORMATION
Comment 1 Sergio 2024-05-31 06:56:27 UTC
This is not just MacOS.

Same issue on Manjaro Linux. Most likely a regression, since I think that kdiff3 was working fine until not long ago.

Seen with

Operating System: Manjaro Linux 
KDE Plasma Version: 6.0.5
KDE Frameworks Version: 6.2.0
Qt Version: 6.7.1
Kernel Version: 6.9.2-1-MANJARO (64-bit)
Graphics Platform: Wayland
Processors: 16 × AMD Ryzen 9 6900HS with Radeon Graphics
Memory: 30.6 GiB of RAM
Graphics Processor: AMD Radeon Graphics
Manufacturer: ASUSTeK COMPUTER INC.
Product Name: ROG Zephyrus G14 GA402RK_GA402RK
System Version: 1.0

Application reports

org.kde.kdiff3: Diff: A <-> B
org.kde.kdiff3: Linediff: A <-> B
org.kde.kdiff3: Enter: calcDiff3LineListUsingAB
org.kde.kdiff3: Leave: calcDiff3LineListUsingAB
Floating point exception (core dumped)
Comment 2 Lari Hotari 2024-06-04 14:13:32 UTC
Same issue on MacOS 14.5 / arm64 / Apple Silicon, installed kdiff3 using homebrew.

I'm using a workaround to install 1.10.7 for MacOS x86_64 and using that until this is fixed. I have shared my workaround custom cask in https://github.com/lhotari/pulsar-contributor-toolbox/blob/master/tools/kdiff3-x86.rb .
Comment 3 michael 2024-06-11 00:08:12 UTC
does the version found here: https://download.kde.org/stable/kdiff3/kdiff3-1.11.1-macos-arm64.dmg.mirrorlist show the same issue?
If so can you get a stack trace with lldb.
Comment 4 Mat 2024-06-11 08:57:12 UTC
Frustratingly for me, it now works using the same version as before (1.11.1 - and I haven't re-installed since raising this bug) after a reboot and a few weeks of elapsed time during which I've likely changed other things too.
Comment 5 Lari Hotari 2024-06-13 11:12:38 UTC
(In reply to Mat from comment #4)
> Frustratingly for me, it now works using the same version as before (1.11.1
> - and I haven't re-installed since raising this bug) after a reboot and a
> few weeks of elapsed time during which I've likely changed other things too.

For me on MacOS 14.5 / arm64, 1.11.1 works for most cases, but it will crash with only certain type contents in the input files.
Comment 6 michael 2024-06-16 12:36:51 UTC
Unless sample files and or stack trace can be provided there is little I can do. KDiff3 has been found to have odd corner cases in the past the require specific input and actions to trigger.
Comment 7 Sergio 2024-06-16 13:47:09 UTC
Providing a test case might not be easy, since code might not be publishable. In any case, if you use the tool yourself, it might be only a matter of time until you get what you need to reproduce the issue. Here, a stack trace might be easier. Can you pls summarize how to get one in Linux?
Comment 8 michael 2024-06-16 17:41:52 UTC
For linux you would need to  either attach the lldb/gdb debugger to kdiff3 or locate the coredump from a crash.
Coredumps are not always generated by default on all setup arch does produce them.
https://lldb.llvm.org/use/map.html  Provides reference for running programs with the debugger attached from the start. The bt command can be used at the when kdiff3 crash to see where this is happening.  lldb is generally the default on MacOS must linux systems will have gdb by default.
Its understandable that some code can't be published. I'll keep on eye out on my end  case too. KDiff3 itself doesn't directly do much with floating point but some of the frameworks its built on do.
Comment 9 simon 2024-06-29 11:55:32 UTC
I can also reproduce this.

OS: Gentoo Linux amd64
kdiff3 version: 1.11.1
KDE Frameworks Version: 5.116.0
Qt Version: 5.15.14
Graphics Platform: Wayland

Thread 1 "kdiff3" received signal SIGFPE, Arithmetic exception.
0x00005555555ef793 in getBestFirstLine (line=..., nofLines=nofLines@entry=2, firstLine=..., visibleLines=visibleLines@entry=0)
    at /usr/src/debug/kde-misc/kdiff3-1.11.1/kdiff3-1.11.1/src/difftextwindow.cpp:589
589             newFirstLine = std::max(0, line - (visibleLines * numberPages) / 3);
(gdb) p visibleLines
$1 = 0
(gdb) list
584         if(nofLines < visibleLines)
585             newFirstLine = std::max(0, (LineType)std::ceil(line - (visibleLines - nofLines) / 2));
586         else
587         {
588             qint32 numberPages = floor(nofLines / visibleLines);
589             newFirstLine = std::max(0, line - (visibleLines * numberPages) / 3);
590         }
591         return newFirstLine;
592     }
593
(gdb) bt
#0  0x00005555555ef793 in getBestFirstLine (line=..., nofLines=nofLines@entry=2, firstLine=...,
    visibleLines=visibleLines@entry=0) at /usr/src/debug/kde-misc/kdiff3-1.11.1/kdiff3-1.11.1/src/difftextwindow.cpp:589
#1  0x00005555555ef8e0 in DiffTextWindow::setFastSelectorRange (this=0x555555cbc1a0, line1=<optimized out>,
    nofLines=<optimized out>) at /usr/src/debug/kde-misc/kdiff3-1.11.1/kdiff3-1.11.1/src/difftextwindow.cpp:600
#2  0x00007ffff68ae4c6 in void doActivate<false>(QObject*, int, void**) () from /usr/lib64/libQt5Core.so.5
#3  0x000055555559afd6 in MergeResultWindow::setFastSelectorRange (this=this@entry=0x555555b97930, _t1=..., _t2=<optimized out>)
    at /usr/src/debug/kde-misc/kdiff3-1.11.1/kdiff3-1.11.1_build/src/kdiff3_autogen/EWIEGA46WW/moc_mergeresultwindow.cpp:476
#4  0x000055555561ca12 in MergeResultWindow::setFastSelector (this=0x555555b97930, i=...)
    at /usr/include/boost/safe_numerics/checked_result.hpp:26
#5  0x000055555561e233 in MergeResultWindow::slotGoTop (this=0x555555b97930)
    at /usr/src/debug/kde-misc/kdiff3-1.11.1/kdiff3-1.11.1/src/mergeresultwindow.cpp:677
#6  MergeResultWindow::merge (this=0x555555b97930, bAutoSolve=true, defaultSelector=<optimized out>, bConflictsOnly=false,
    bWhiteSpaceOnly=<optimized out>) at /usr/src/debug/kde-misc/kdiff3-1.11.1/kdiff3-1.11.1/src/mergeresultwindow.cpp:416
#7  0x000055555561e5cc in MergeResultWindow::init (this=0x555555b97930, pLineDataA=..., sizeA=..., pLineDataB=..., sizeB=...,
    pLineDataC=..., sizeC=..., pDiff3LineList=0x555555748450, pTotalDiffStatus=0x555555748f60, bAutoSolve=true)
    at /usr/src/debug/kde-misc/kdiff3-1.11.1/kdiff3-1.11.1/src/mergeresultwindow.cpp:132
#8  0x00005555555dca66 in KDiff3App::mainInit (this=this@entry=0x555555748000, pTotalDiffStatus=0x555555748f60, inFlags=...,
    inFlags@entry=...) at /usr/src/debug/kde-misc/kdiff3-1.11.1/kdiff3-1.11.1/src/pdiff.cpp:380
#9  0x00005555555acf02 in KDiff3App::doFileCompare (this=0x555555748000) at /usr/include/qt5/QtCore/qflags.h:121
#10 KDiff3App::completeInit (this=0x555555748000, fn1=..., fn2=..., fn3=...)
    at /usr/src/debug/kde-misc/kdiff3-1.11.1/kdiff3-1.11.1/src/kdiff3.cpp:493
#11 0x00005555555a39f0 in KDiff3Shell::KDiff3Shell (this=0x555555738ba0, fn1=..., fn2=..., fn3=..., __in_chrg=<optimized out>,
    __vtt_parm=<optimized out>) at /usr/src/debug/kde-misc/kdiff3-1.11.1/kdiff3-1.11.1/src/kdiff3_shell.cpp:39
#12 0x00005555555a1bb0 in operator() (__closure=0x5555557432d0)
    at /usr/src/debug/kde-misc/kdiff3-1.11.1/kdiff3-1.11.1/src/main.cpp:195
#13 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, main(qint32, char**)::<lambda()> >::call (
    arg=<optimized out>, f=...) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:146
#14 QtPrivate::Functor<main(qint32, char**)::<lambda()>, 0>::call<QtPrivate::List<>, void> (arg=<optimized out>, f=...)
    at /usr/include/qt5/QtCore/qobjectdefs_impl.h:256
#15 QtPrivate::QFunctorSlotObject<main(qint32, char**)::<lambda()>, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=<optimized out>, this_=0x5555557432c0, r=<optimized out>, a=<optimized
out>,
    ret=<optimized out>) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:443
#16 0x00007ffff68a4d7e in QObject::event(QEvent*) () from /usr/lib64/libQt5Core.so.5
#17 0x00007ffff72fa1fe in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib64/libQt5Widgets.so.5
#18 0x00007ffff687aee8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib64/libQt5Core.so.5
#19 0x00007ffff687e3c3 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) ()
   from /usr/lib64/libQt5Core.so.5
#20 0x00007ffff68cc473 in postEventSourceDispatch(_GSource*, int (*)(void*), void*) () from /usr/lib64/libQt5Core.so.5
#21 0x00007ffff5521ff2 in g_main_dispatch () from /usr/lib64/libglib-2.0.so.0
#22 0x00007ffff55251a7 in g_main_context_iterate_unlocked.isra () from /usr/lib64/libglib-2.0.so.0
#23 0x00007ffff55257cc in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0


This looks like an integer divide-by-zero in getBestFirstLine. I am using the following workaround to prevent the crash:

--- A/src/difftextwindow.cpp
+++ B/src/difftextwindow.cpp
@@ -583,7 +583,7 @@

     if(nofLines < visibleLines)
         newFirstLine = std::max(0, (LineType)std::ceil(line - (visibleLines - nofLines) / 2));
-    else
+    else if(visibleLines > 0)
     {
         qint32 numberPages = floor(nofLines / visibleLines);
         newFirstLine = std::max(0, line - (visibleLines * numberPages) / 3);
Comment 10 Sam James 2024-06-30 12:41:19 UTC
(In reply to simon from comment #9)
> I can also reproduce this.

Thanks, I just came here with the same backtrace and proposed patch.
Comment 11 Sam James 2024-06-30 12:44:54 UTC
Sample files:
```
cd /tmp
touch a b
echo hi > b
kdiff3 a b
```
Comment 12 michael 2024-07-04 20:21:46 UTC
Git commit 5965591080306c66a48e961d264f212989fdae94 by Michael Reeves.
Committed on 04/07/2024 at 20:21.
Pushed by mreeves into branch '1.11'.

Handle 0 height QWidget in getNofVisibleLines
FIXED-IN:1.11.3

M  +5    -3    src/difftextwindow.cpp
M  +2    -1    src/mergeresultwindow.cpp

https://invent.kde.org/sdk/kdiff3/-/commit/5965591080306c66a48e961d264f212989fdae94
Comment 13 michael 2024-07-04 20:22:13 UTC
Git commit 8fa35b7d3155854f2ebda4c1a85af3e6a7f518f7 by Michael Reeves.
Committed on 04/07/2024 at 15:39.
Pushed by mreeves into branch 'master'.

Handle 0 height QWidget in getNofVisibleLines
FIXED-IN:1.11.3

M  +5    -3    src/difftextwindow.cpp
M  +2    -1    src/mergeresultwindow.cpp

https://invent.kde.org/sdk/kdiff3/-/commit/8fa35b7d3155854f2ebda4c1a85af3e6a7f518f7
Comment 14 michael 2024-07-04 21:15:11 UTC
*** Bug 489494 has been marked as a duplicate of this bug. ***