Bug 333236

Summary: Illegal Instruction 4 when touching any part of the code dealing with scheduled transactions
Product: [Applications] kmymoney Reporter: A.C. <ac>
Component: generalAssignee: KMyMoney Devel Mailing List <kmymoney-devel>
Status: RESOLVED WORKSFORME    
Severity: crash CC: onet.cristian
Priority: NOR    
Version: git (master)   
Target Milestone: ---   
Platform: Mint (Ubuntu based)   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: On the computer this fails on this causes an illegal instruction on scheduled transactions
Crash log from clicking on forecast charts when no loans are present

Description A.C. 2014-04-09 17:04:15 UTC
After changing from a hex-core AMD processor to a quad-core AMD processor I was no longer able to open my .kmy file.  After some troubleshooting the problem appears to be limited to scheduled transactions.  The issue is 100% reproducible on the system with the processor swap but is not reproducible on my laptop (also running Linux Mint).  I've attached the anonomized file that causes this problem.  The traceback can be found at: http://codepad.org/utul0ca2

Reproducible: Always




Application: KMyMoney (kmymoney), signal: Illegal instruction
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[Current thread is 1 (Thread 0x7fbe76d967c0 (LWP 4385))]

Thread 4 (Thread 0x7fbe5c569700 (LWP 4386)):
#0  0x00007fbe6c6ac06b in __pthread_mutex_unlock_usercnt (mutex=0x185c060, decr=1) at pthread_mutex_unlock.c:58
#1  0x00007fbe6c01f3d1 in g_mutex_unlock () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2  0x00007fbe6bfdefbb in g_main_context_query () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007fbe6bfdf612 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4  0x00007fbe6bfdfb0a in g_main_loop_run () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5  0x00007fbe6380db66 in ?? () from /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
#6  0x00007fbe6c0040f5 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#7  0x00007fbe6c6a8f6e in start_thread (arg=0x7fbe5c569700) at pthread_create.c:311
#8  0x00007fbe7101a9cd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113

Thread 3 (Thread 0x7fbe5bd68700 (LWP 4387)):
#0  0x00007fbe7100df7d in poll () at ../sysdeps/unix/syscall-template.S:81
#1  0x00007fbe6bfdf6a4 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2  0x00007fbe6bfdf7ac in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007fbe6bfdf7f9 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4  0x00007fbe6c0040f5 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5  0x00007fbe6c6a8f6e in start_thread (arg=0x7fbe5bd68700) at pthread_create.c:311
#6  0x00007fbe7101a9cd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113

Thread 2 (Thread 0x7fbe5b567700 (LWP 4388)):
#0  pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
#1  0x00007fbe6c01f705 in g_cond_wait_until () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2  0x00007fbe6bfb5c51 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007fbe6bfb61db in g_async_queue_timeout_pop () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4  0x00007fbe6c004b86 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5  0x00007fbe6c0040f5 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#6  0x00007fbe6c6a8f6e in start_thread (arg=0x7fbe5b567700) at pthread_create.c:311
#7  0x00007fbe7101a9cd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113

Thread 1 (Thread 0x7fbe76d967c0 (LWP 4385)):
[KCrash Handler]
#5  0x00007fbe70ccfac6 in __gmpq_get_d () from /usr/local/lib/libgmp.so.10
#6  0x00007fbe7699c766 in MyMoneyForecast::calculateAutoLoan (schedule=..., transaction=..., balances=...) at /home/ac/Downloads/kmymoney-git/kmymoney/mymoney/mymoneyforecast.cpp:1264
#7  0x00007fbe769a397f in MyMoneyForecast::addScheduledTransactions (this=this@entry=0x1c01978) at /home/ac/Downloads/kmymoney-git/kmymoney/mymoney/mymoneyforecast.cpp:690
#8  0x00007fbe769a43a4 in MyMoneyForecast::doFutureScheduledForecast (this=this@entry=0x1c01978) at /home/ac/Downloads/kmymoney-git/kmymoney/mymoney/mymoneyforecast.cpp:527
#9  0x00007fbe769a46a8 in MyMoneyForecast::doForecast (this=0x1c01978) at /home/ac/Downloads/kmymoney-git/kmymoney/mymoney/mymoneyforecast.cpp:91
#10 0x00000000005209fc in KHomeView::doForecast (this=this@entry=0x1c76600) at /home/ac/Downloads/kmymoney-git/kmymoney/views/khomeview.cpp:1619
#11 0x0000000000524581 in KHomeView::showPayments (this=this@entry=0x1c76600) at /home/ac/Downloads/kmymoney-git/kmymoney/views/khomeview.cpp:358
#12 0x000000000052c4f8 in KHomeView::loadView (this=0x1c76600) at /home/ac/Downloads/kmymoney-git/kmymoney/views/khomeview.cpp:241
#13 0x000000000052c855 in KHomeView::slotLoadView (this=0x1c76600) at /home/ac/Downloads/kmymoney-git/kmymoney/views/khomeview.cpp:172
#14 0x000000000052d905 in KHomeView::qt_static_metacall (_o=<optimized out>, _id=<optimized out>, _a=<optimized out>, _c=<optimized out>) at /home/ac/Downloads/kmymoney-git/kmymoney/views/khomeview.moc:67
#15 0x00007fbe72bc1a58 in QMetaObject::activate (sender=sender@entry=0x7fbe76bcb680 <MyMoneyFile::file>, m=m@entry=0x7fbe76bc97c0 <MyMoneyFile::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x0) at kernel/qobject.cpp:3539
#16 0x00007fbe7695cf20 in MyMoneyFile::dataChanged (this=this@entry=0x7fbe76bcb680 <MyMoneyFile::file>) at /home/ac/Downloads/kmymoney-git/kmymoney/mymoney/mymoneyfile.moc:113
#17 0x00007fbe769684f9 in MyMoneyFile::attachStorage (this=0x7fbe76bcb680 <MyMoneyFile::file>, storage=storage@entry=0x1d602a0) at /home/ac/Downloads/kmymoney-git/kmymoney/mymoney/mymoneyfile.cpp:338
#18 0x00000000004bcad2 in KMyMoneyView::readFile (this=0x1c36180, url=...) at /home/ac/Downloads/kmymoney-git/kmymoney/views/kmymoneyview.cpp:848
#19 0x000000000049409c in KMyMoneyApp::slotFileOpenRecent (this=0x1862100, url=...) at /home/ac/Downloads/kmymoney-git/kmymoney/kmymoney.cpp:1541
#20 0x000000000045a163 in runKMyMoney (splash=splash@entry=0x1960960, a=0x16b78d0) at /home/ac/Downloads/kmymoney-git/kmymoney/main.cpp:269
#21 0x0000000000457c58 in main (argc=2, argv=0x7fff54d15698) at /home/ac/Downloads/kmymoney-git/kmymoney/main.cpp:178
Comment 1 A.C. 2014-04-09 17:08:53 UTC
Created attachment 86019 [details]
On the computer this fails on this causes an illegal instruction on scheduled transactions
Comment 2 A.C. 2014-04-09 17:15:29 UTC
This was discovered on an AMD 64-bit system with the following characteristics:

$ uname -a
Linux silvermine 3.11.0-19-generic #33-Ubuntu SMP Tue Mar 11 18:48:34 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

lsb_release -a
No LSB modules are available.
Distributor ID:	LinuxMint
Description:	Linux Mint 16 Petra
Release:	16
Codename:	petra

$ cat /proc/cpuinfo 
processor	: 0
vendor_id	: AuthenticAMD
cpu family	: 16
model		: 4
model name	: AMD Phenom(tm) II X4 965 Processor
stepping	: 2
microcode	: 0x10000db
cpu MHz		: 800.000
cache size	: 512 KB
physical id	: 0
siblings	: 4
core id		: 0
cpu cores	: 4
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 5
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm 3dnowext 3dnow constant_tsc rep_good nopl nonstop_tsc extd_apicid pni monitor cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt hw_pstate npt lbrv svm_lock nrip_save
bogomips	: 6817.06
TLB size	: 1024 4K pages
clflush size	: 64
cache_alignment	: 64
address sizes	: 48 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate

libgmp-dev is version 2:5.1.2+dfsg-2ubuntu1
Comment 3 A.C. 2014-04-10 04:34:29 UTC
The exact version of libgmp and libalkimia4 on the system that is failing is:

libgmp10:amd64 (2:5.1.2+dfsg-2ubuntu1)
libgmp-dev:amd64 (2:5.1.2+dfsg-2ubuntu1)
libalkimia4_4.3.2-1.1_amd64.deb (4.3.2-1.1)

I have attempted to delete all schedules manually which allows me to open the file on the affected computer but I am unable to perform an OFX update as it immediately crashes with the same error.  I'll continue to investigate but I'm not sure what else to try.
Comment 4 Alvaro Soliverez 2014-04-10 11:28:57 UTC
Based on the original trace, there's something weird happening. Here's the relevant snippet of code.

      MyMoneyMoney balance;
      if (balances.count() == 0)
        balance = MyMoneyFile::instance()->balance(acc.id(), dueDate.addDays(-1));
      else
        balance = balances[acc.id()];

      // FIXME: for now, we only support interest calculation at the end of the period
      calc.setBep();
      // FIXME: for now, we only support periodic compounding
      calc.setDisc();

      calc.setPF(MyMoneySchedule::eventsPerYear(schedule.occurrence()));
      MyMoneySchedule::occurrenceE compoundingOccurrence = static_cast<MyMoneySchedule::occurrenceE>(acc.interestCompounding());
      if (compoundingOccurrence == MyMoneySchedule::OCCUR_ANY)
        compoundingOccurrence = schedule.occurrence();

      calc.setCF(MyMoneySchedule::eventsPerYear(compoundingOccurrence));

      calc.setPv(balance.toDouble());   <--- this is line 1264.

I think the only way this might happen, is if QMap balances does not actually contain acc.id(), but it should still return a default MyMoneyMoney value, which is 0, and is a normal case
Comment 5 A.C. 2014-04-10 16:13:32 UTC
There is a very real possibility that the way I structured the loan(s) in that file is the problem.  Even in anonomized form you can see that something is fishy.  I don't want to publicly disclose too much data about the loan(s) but suffice it to say I configured it such that no payments would be scheduled until the last day but interest would calculate as being accrued for the duration of the loan (i.e. sort of like a non-compounded loan with a baloon payment, although this grossly miscategorizes the actual intent of the loan - like I say, I have to walk a fine line between describing the loan without creating incorrect public assumptions :).

I tried removing the schedules from the loan but it was still not possible to use OFX connect.  I can try eradicating the questionable loan(s) altogether as a next step; I have fairly high confidence that the problem will go away.
Comment 6 A.C. 2014-04-11 16:06:33 UTC
Created attachment 86045 [details]
Crash log from clicking on forecast charts when no loans are present

I've now deleted every loan with unusual characteristics but simple things such as going to forecast charts or doing an OFX update still cause the illegal instruction.  I'm starting to really suspect libgmp and I'm tempted to figure out how to build *that* from source next.
Comment 7 Cristian Oneț 2014-04-11 16:59:48 UTC
I could bet that it's libgmp since it uses CPU specific assembly code which, if not built for the correct platform, would result in this kind of error.
Comment 8 A.C. 2014-04-15 02:25:55 UTC
With help from Hei_Ku in #kmymoney I've compiled everything *extremely* cleanly by doing make distclean and make clean on everything.  I then built libgmp 5.1, built libalkimia, built kymymoney, and reproduced the same crash: http://codepad.org/BSk0sM4l

As an aside, I completed a full memory scan and found no errors.  I've also done a make test on kmymoney with the result "100% tests passed, 0 tests failed out of 30".  I consistently see crashes when using my non-anonomized file to do an OFX or by going to forecast -> charts.  A test of doubles in libgmp is likely needed next, per Hei_Ku.
Comment 9 Alvaro Soliverez 2014-04-15 02:35:08 UTC
There are crashes both when instantiating a new MyMoneyMoney from a double, and when calling  method toDouble.
I'm adding an additional test in mymoneymoneytest to check these cases, both of which are not tested at the moment.
Comment 10 A.C. 2014-04-16 16:35:43 UTC
After Alvaro's changes, the make test still reports 100% tests passed, 0 tests failed out of 30.  Making changes such as adding .toString() everywhere gets around the crash but causes the units to be off in difficult to understand ways when doing an OFX import, such as an $86.00 transaction showing up as $0.08 but a later transaction showing up with the correct value.
Comment 11 Cristian Oneț 2014-09-23 14:03:07 UTC
What's the status of this issue? Can the crash be reproduced using the attached anonymous file?
Comment 12 Cristian Oneț 2014-09-23 20:44:07 UTC
The anonymous file opens without any issues over here, you said you built libgmp yourself while testing with Alvaro, did the gmp tests run without failure?
Comment 13 A.C. 2014-09-29 19:11:02 UTC
I have done some additional testing on this issue and I am unable to recreate it after booting from Linux Mint 17 on the *exact same hardware*.  I can only assume that the initial swap of the CPU caused an extremely deep bug that will hopefully never blight anyone ever again.  For now, I believe this is not reproducible but this public record can stand as a monument to any who follow this rabbit hole.
Comment 14 Cristian Oneț 2014-09-29 20:50:03 UTC
OK, thanks for the follow-up.