Bug 210769 - Plasma random crash (time dataengine) [libc-related, tzset, KSystemTimeZoneBackend::offset, KSystemTimeZoneBackend::offsetAtUtc]
Summary: Plasma random crash (time dataengine) [libc-related, tzset, KSystemTimeZoneBa...
Status: RESOLVED FIXED
Alias: None
Product: kdepimlibs
Classification: Applications
Component: kholidays (show other bugs)
Version: unspecified
Platform: Unlisted Binaries Linux
: NOR crash
Target Milestone: ---
Assignee: kdelibs bugs
URL:
Keywords:
: 210875 228085 241122 241296 241308 241319 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-10-16 10:56 UTC by charizard25_hk
Modified: 2015-01-27 13:06 UTC (History)
10 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Valgrind log (11.35 KB, application/octet-stream)
2010-06-10 21:35 UTC, David Hubner
Details
New crash information added by DrKonqi (7.10 KB, text/plain)
2010-06-11 21:24 UTC, Unknown
Details
KHols Patch file (491 bytes, patch)
2010-06-11 23:43 UTC, David Hubner
Details
True KHols fix (1.52 KB, patch)
2010-06-12 03:22 UTC, David Hubner
Details

Note You need to log in before you can comment on or make changes to this bug.
Description charizard25_hk 2009-10-16 10:56:12 UTC
Application that crashed: plasma-desktop
Version of the application: 0.3
KDE Version: 4.3.2 (KDE 4.3.2)
Qt Version: 4.5.2
Operating System: Linux 2.6.30-020630-generic i686
Distribution: Ubuntu 9.04

 -- Backtrace:
Application: Plasma Workspace (kdeinit4), signal: Aborted
[Current thread is 0 (LWP 3607)]

Thread 2 (Thread 0xa930bb90 (LWP 3608)):
#0  0xb80aa430 in __kernel_vsyscall ()
#1  0xb65c20e5 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/tls/i686/cmov/libpthread.so.0
#2  0xb67a22ed in pthread_cond_wait () from /lib/tls/i686/cmov/libc.so.6
#3  0xb7ea9172 in QWaitCondition::wait (this=0x8cb7680, mutex=0x8cb767c, time=4294967295) at thread/qwaitcondition_unix.cpp:87
#4  0xb77e5ac2 in QHostInfoAgent::run (this=0x8cb7670) at kernel/qhostinfo.cpp:260
#5  0xb7ea8132 in QThreadPrivate::start (arg=0x8cb7670) at thread/qthread_unix.cpp:188
#6  0xb65be4ff in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#7  0xb679349e in clone () from /lib/tls/i686/cmov/libc.so.6

Thread 1 (Thread 0xb60cba10 (LWP 3607)):
[KCrash Handler]
#6  0xb80aa430 in __kernel_vsyscall ()
#7  0xb66da6d0 in raise () from /lib/tls/i686/cmov/libc.so.6
#8  0xb66dc098 in abort () from /lib/tls/i686/cmov/libc.so.6
#9  0xb671824d in ?? () from /lib/tls/i686/cmov/libc.so.6
#10 0xb671f009 in ?? () from /lib/tls/i686/cmov/libc.so.6
#11 0xb6720b8d in ?? () from /lib/tls/i686/cmov/libc.so.6
#12 0xb67229c5 in malloc () from /lib/tls/i686/cmov/libc.so.6
#13 0xb673f9f6 in ?? () from /lib/tls/i686/cmov/libc.so.6
#14 0xb673eb15 in ?? () from /lib/tls/i686/cmov/libc.so.6
#15 0xb673ee5d in tzset () from /lib/tls/i686/cmov/libc.so.6
#16 0xb7cd4071 in KSystemTimeZoneBackend::offset (this=0x98ab0b0, caller=0xbf993984, t=1255683195) at /build/buildd/kde4libs-4.3.2/kdecore/date/ksystemtimezone.cpp:608
#17 0xb7cd2b3d in KSystemTimeZoneBackend::offsetAtUtc (this=0x98ab0b0, caller=0xbf993984, utcDateTime=@0xbf9938f0) at /build/buildd/kde4libs-4.3.2/kdecore/date/ksystemtimezone.cpp:592
#18 0xb7ccbb00 in KTimeZone::offsetAtUtc (this=0xbf993984, utcDateTime=@0xbf9938f0) at /build/buildd/kde4libs-4.3.2/kdecore/date/ktimezone.cpp:799
#19 0xb7cd078a in KTimeZone::toZoneTime (this=0xbf993984, utcDateTime=@0xbf9938f0, secondOccurrence=0xbf9938fb) at /build/buildd/kde4libs-4.3.2/kdecore/date/ktimezone.cpp:768
#20 0xb7cbf603 in KDateTimePrivate::toZone (this=0x992c648, zone=@0xbf993984, local=@0xbf99397c) at /build/buildd/kde4libs-4.3.2/kdecore/date/kdatetime.cpp:726
#21 0xb7cbf727 in KDateTimePrivate::newToZone (this=0x992c648, newd=0x98e5a60, zone=@0xbf993984, local=@0xbf99397c) at /build/buildd/kde4libs-4.3.2/kdecore/date/kdatetime.cpp:742
#22 0xb7cc99b3 in KDateTime::toTimeSpec (this=0xbf9939c8, spec=@0xbf993a74) at /build/buildd/kde4libs-4.3.2/kdecore/date/kdatetime.cpp:994
#23 0xb7cc9a5e in KDateTime::currentDateTime (spec=@0xbf993a74) at /build/buildd/kde4libs-4.3.2/kdecore/date/kdatetime.cpp:1263
#24 0xa89fa661 in ?? () from /usr/lib/kde4/plasma_engine_time.so
#25 0xa89f85b9 in ?? () from /usr/lib/kde4/plasma_engine_time.so
#26 0xb5e5d515 in Plasma::DataEnginePrivate::internalUpdateSource (this=0x8d178c0, source=0xbf993a74) at /build/buildd/kde4libs-4.3.2/plasma/dataengine.cpp:518
#27 0xb5e5f85a in Plasma::DataEngine::qt_metacall (this=0x8d02f30, _c=QMetaObject::InvokeMetaMethod, _id=5, _a=0xbf993c1c) at /build/buildd/kde4libs-4.3.2/obj-i486-linux-gnu/plasma/dataengine.moc:118
#28 0xa89f896a in ?? () from /usr/lib/kde4/plasma_engine_time.so
#29 0xb7fb21b8 in QMetaObject::activate (sender=0x8d059d8, from_signal_index=6, to_signal_index=6, argv=0xbf993c1c) at kernel/qobject.cpp:3113
#30 0xb7fb2e42 in QMetaObject::activate (sender=0x8d059d8, m=0xb5f99124, local_signal_index=2, argv=0xbf993c1c) at kernel/qobject.cpp:3187
#31 0xb5e5b083 in Plasma::DataContainer::updateRequested (this=0x8d059d8, _t1=0x8d059d8) at /build/buildd/kde4libs-4.3.2/obj-i486-linux-gnu/plasma/datacontainer.moc:107
#32 0xb5e89bc0 in Plasma::SignalRelay::timerEvent (this=0x8d99ff8, event=0xbf99407c) at /build/buildd/kde4libs-4.3.2/plasma/private/datacontainer_p.cpp:149
#33 0xb7fad16f in QObject::event (this=0x8d99ff8, e=0xbf99407c) at kernel/qobject.cpp:1075
#34 0xb6a58d3c in QApplicationPrivate::notify_helper (this=0x864b250, receiver=0x8d99ff8, e=0xbf99407c) at kernel/qapplication.cpp:4056
#35 0xb6a6103e in QApplication::notify (this=0x8628120, receiver=0x8d99ff8, e=0xbf99407c) at kernel/qapplication.cpp:3603
#36 0xb756949d in KApplication::notify (this=0x8628120, receiver=0x8d99ff8, event=0xbf99407c) at /build/buildd/kde4libs-4.3.2/kdeui/kernel/kapplication.cpp:302
#37 0xb7f9cbcb in QCoreApplication::notifyInternal (this=0x8628120, receiver=0x8d99ff8, event=0xbf99407c) at kernel/qcoreapplication.cpp:610
#38 0xb7fcbd51 in QTimerInfoList::activateTimers (this=0x864dc54) at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:213
#39 0xb7fc83a0 in timerSourceDispatch (source=0x864dc20) at kernel/qeventdispatcher_glib.cpp:165
#40 0xb660bb88 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#41 0xb660f0eb in ?? () from /usr/lib/libglib-2.0.so.0
#42 0xb660f268 in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0
#43 0xb7fc82f8 in QEventDispatcherGlib::processEvents (this=0x864af68, flags={i = -1080475144}) at kernel/qeventdispatcher_glib.cpp:327
#44 0xb6afaa75 in QGuiEventDispatcherGlib::processEvents (this=0x864af68, flags={i = -1080475096}) at kernel/qguieventdispatcher_glib.cpp:202
#45 0xb7f9b1fa in QEventLoop::processEvents (this=0xbf9942a0, flags={i = -1080475032}) at kernel/qeventloop.cpp:149
#46 0xb7f9b642 in QEventLoop::exec (this=0xbf9942a0, flags={i = -1080474968}) at kernel/qeventloop.cpp:201
#47 0xb7f9dae9 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:888
#48 0xb6a58bb7 in QApplication::exec () at kernel/qapplication.cpp:3525
#49 0xb4c1c2f0 in kdemain () from /usr/lib/libkdeinit4_plasma-desktop.so
#50 0x0804e27d in launch (argc=1, _name=0x85e457c "/usr/bin/plasma-desktop", args=0x85e4594 "", cwd=0x0, envc=0, envs=0x85e4598 "", reset_env=false, tty=0x0, avoid_loops=false, 
    startup_id_str=0x805136d "0") at /build/buildd/kde4libs-4.3.2/kinit/kinit.cpp:677
#51 0x0804ea5d in handle_launcher_request (sock=7, who=<value optimized out>) at /build/buildd/kde4libs-4.3.2/kinit/kinit.cpp:1169
#52 0x0804efe5 in handle_requests (waitForPid=0) at /build/buildd/kde4libs-4.3.2/kinit/kinit.cpp:1362
#53 0x0804fbca in main (argc=2, argv=0xbf994a94, envp=0xbf994aa0) at /build/buildd/kde4libs-4.3.2/kinit/kinit.cpp:1793

Reported using DrKonqi
Comment 1 Dario Andres 2009-10-17 18:11:34 UTC
*** Bug 210875 has been marked as a duplicate of this bug. ***
Comment 2 Dario Andres 2009-10-17 18:35:31 UTC
This could be an issue with libc, and/or caused by some update. Did you had some package update lately?
It would be useful if you could recognize the moment this crash is happening; it is related to the time dataengine (the one that the Plasma clocks use..) so it may be related to some specific time.

A valgrind log could also be useful, but that is more advance task to achieve:
http://techbase.kde.org/Development/Tutorials/Debugging/How_to_create_useful_crash_reports#Retrieving_a_backtrace_with_Valgrind

Thanks.
Comment 3 Dario Andres 2009-12-07 00:47:30 UTC
Waiting for feedback.
Comment 4 Beat Wolf 2010-06-08 23:07:30 UTC
*** Bug 228085 has been marked as a duplicate of this bug. ***
Comment 5 Christopher Neufeld 2010-06-10 02:04:25 UTC
*** Bug 241122 has been marked as a duplicate of this bug. ***
Comment 6 Christopher Neufeld 2010-06-10 02:06:23 UTC
I have a valgrind run, it shows the problem as being under ::tzset() in glibc.  See my comments on 241122.  I believe this bug can be closed.  Here's the relevant portion of the valgrind when running on glibc-2.7:

==15150== Invalid free() / delete / delete[]
==15150==    at 0x4B1FB2E: free (vg_replace_malloc.c:323)
==15150==    by 0xAFD57BA: (within /lib64/libc-2.7.so)
==15150==    by 0xAFD5388: (within /lib64/libc-2.7.so)
==15150==    by 0x491C508: _vgnU_freeres (vg_preloaded.c:60)
==15150==    by 0xAF47EBD: _IO_file_read (fileops.c:1199)
==15150==    by 0xAF48E47: _IO_file_underflow@@GLIBC_2.2.5 (fileops.c:596)
==15150==    by 0xAF479F7: _IO_file_xsgetn (fileops.c:1435)
==15150==    by 0xAF46FDD: fread_unlocked (iofread_u.c:45)
==15150==    by 0xAF66AC6: __tzfile_read (tzfile.c:205)
==15150==    by 0xAF65D59: tzset_internal (tzset.c:422)
==15150==    by 0xAF6607F: tzset (tzset.c:578)
==15150==    by 0x8CBEE2F: KSystemTimeZoneBackend::offset(KTimeZone const*, long
) const (ksystemtimezone.cpp:642)
==15150==  Address 0x4050800 is not stack'd, malloc'd or (recently) free'd
==15150==
Comment 7 Beat Wolf 2010-06-10 16:46:15 UTC
*** Bug 241296 has been marked as a duplicate of this bug. ***
Comment 8 Beat Wolf 2010-06-10 16:46:18 UTC
*** Bug 241308 has been marked as a duplicate of this bug. ***
Comment 9 David Hubner 2010-06-10 16:54:56 UTC
Happens in glibc 2.12 as well.
Comment 10 David Hubner 2010-06-10 17:07:25 UTC
Just some more information. Does not happen in 4.4, only in 4.5 beta 2 with me. Both using the same glibc 2.12. 

Original bug post 241308
Comment 11 Aaron J. Seigo 2010-06-10 17:59:14 UTC
@David: it probably happens for you in 4.5 but not 4.4 because kholidays has been significantly changed between those two releases (for the better :) and is now probably tripping the same bug that the time engine was in this report.
Comment 12 David Hubner 2010-06-10 18:05:43 UTC
@Aaron Has it been upstreamed? Or should I post a bug on the glibc bugzilla?
Comment 13 Aaron J. Seigo 2010-06-10 18:27:59 UTC
@David: i really have no idea. sorry :( no time to track upstreams these days.. too many of them and too few of me :)
Comment 14 Christopher Neufeld 2010-06-10 18:32:37 UTC
I'm building a KDE checkout now, I'll valgrind the plasma-desktop binary again once it's ready, against my fresh new glibc-2.11.  If there's still badness going on underneath there, even if it no longer results in a crash at logout, I'll do some debugging, check the glibc-git tree, and submit a glibc bug with my findings if it's not yet addressed.
Comment 15 Christopher Neufeld 2010-06-10 20:58:41 UTC
Well, I can't reproduce the crash with revision 1136714.  Valgrind on plasma-desktop does not now show a bad free underneath tzset().  That doesn't mean that glibc doesn't still have the bug, but I can't reproduce the crashes anymore, using that revision of KDE and glibc-2.11.
Comment 16 David Hubner 2010-06-10 21:34:05 UTC
Yes, it seems not to be related to the old one. 

I valgrinded it and got the following attachment. I also commented out ~HolidayParserDriverPlan() in holidayparserdriverplan.cpp to test if something was being destroyed that should not be and everything was fine. 

Seemed a bit odd so uncommented it and made a new account and tried it. New account seems fine so must be a config/data file that is effecting it in .kde4.

I shall run tests tomorrow to find out what is messing it around and then find out why!
Comment 17 David Hubner 2010-06-10 21:35:30 UTC
Created attachment 47872 [details]
Valgrind log
Comment 18 Beat Wolf 2010-06-10 22:46:46 UTC
*** Bug 241319 has been marked as a duplicate of this bug. ***
Comment 19 John Layt 2010-06-10 23:02:51 UTC
Just stumbled across this bug by chance, not sure how it got connected back
from the KHolidays bugs and crashes?  Is it something deeper that KHolidays is
triggering?  Can someone elaborate?

I just started to see these random crashes in KHolidays today and wondered what
I'd messed up.  There's several reports getting logged.  What I'm doing to
trigger it is in the Calendar Plasmoid I can change the Holiday Region as much
as I like and it's happy, but as soon as I change the Calendar System then it
crashes in the scannerReset() call, which is just a call to glibc rewind().

I'm running glibc 2.10.1 on openSuse 11.2 x64.

Note that the lpp/ypp files are run through bison and flex to generate code.

Anything I can do to help further?

If we need to, I can disable the new holiday parser and fall back to the old
parser and hope it doesn't trigger the bug.  We loose the alternative calendar
systems and a few new calculation features like that, but we still keep the new
api and metadata so no apps would be affected.
Comment 20 David Hubner 2010-06-10 23:16:11 UTC
@John probably better to keep it in so we can find out where this problem lies. I am going to go on a mass debug session tomorrow with this as I can duplicate it by moving my old .kde4 folder over and logging in.
Comment 21 John Layt 2010-06-10 23:25:44 UTC
OK, thanks.  But at least we have a fall-back if we can't figure it out or can't otherwise work-around it.  I'll go over the holidays code anyway just to make sure 

Good luck!
Comment 22 John Layt 2010-06-11 00:39:11 UTC
I've found if I don't cache the HolidayRegion object in the plasma calendar DataEngine but instead delete it immediately after using it then my crashes go away.  I'd guess this is because the file isn't kept open for ages waiting for something else to mess it up.  It's not a fix, but it's a better work-around than reverting to the old parser.
Comment 23 Unknown 2010-06-11 21:24:12 UTC
Created attachment 47913 [details]
New crash information added by DrKonqi

plasma-desktop (0.3) on KDE Platform 4.4.85 (KDE 4.4.85 (KDE 4.5 Beta2)) using Qt 4.7.0

- What I was doing when the application crashed:

As in the bug report, plasma crashed during logout.

-- Backtrace (Reduced):
#10 0xb601d2dd in __libc_message (do_abort=2, fmt=0xb60dc298 "*** glibc detected *** %s: %s: 0x%s ***\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:170
#11 0xb6023141 in malloc_printerr (action=<value optimized out>, str=0x6 <Address 0x6 out of bounds>, ptr=0xa538b80) at malloc.c:6197
[...]
#13 0xb6013252 in _IO_new_fclose (fp=0xa538b80) at iofclose.c:88
#14 0xaa055e41 in KHolidays::HolidayParserDriverPlan::scannerTerminate (this=0xa538b10) at holidayscannerplan.lpp:311
#15 0xaa0468b7 in ~HolidayParserDriverPlan (this=0xa538b10, __in_chrg=<value optimized out>)
    at /home/porttmp/portage/kde-base/kdepimlibs-4.4.85/work/kdepimlibs-4.4.85/kholidays/parsers/plan2/holidayparserdriverplan.cpp:61
Comment 24 Aaron J. Seigo 2010-06-11 21:53:34 UTC
NEW'ing and re-assigning to kdepimlibs then. thanks for all the follow ups!
Comment 25 David Hubner 2010-06-11 23:42:19 UTC
Seems sometimes the file does not open and when you do rewind or terminate it crashes. Attached file solved the issue for me, at least I think it did.. was a nightmare to reproduce!
Comment 26 David Hubner 2010-06-11 23:43:46 UTC
Created attachment 47916 [details]
KHols Patch file
Comment 27 David Hubner 2010-06-11 23:53:34 UTC
How this works by the way I have no idea, as if you delete a null pointer nothing happens ( should not crash ) and rewind should work with a null pointer. 

So I would take this with a "Dunno, probably not fixed". For the debugging I did it seems that the deconstructor of HolidayParserDriverPlan is being called twice. 

How that is possible I don't know. I am unable to replicate the crash at the moment so if it pops it head again I shall give it another go!
Comment 28 John Layt 2010-06-12 00:30:41 UTC
Thanks for the efforts David.  I'll apply the patch to the lpp and regenerate the code to see if it fixes the problem here.

I'm still a little mystified as to how the KHolidays bug has been linked back
to this bug, could someone explain?  The traces don't look anything alike to
me.  Are we sure the KHoliday crash is caused by the possible glibc bug in
tzset()?  I need to understand so I can try figure out what underlying issue in KHolidays triggers it.  I get the crash when changing calendar system in the plasmoid, which could conceivably be causing a call to tzset somewhere, but I'm sceptical that it or the other 2 crash scenario's I've seen reported would ever need to touch timezones.  Are we sure it's not just KHolidays loosing track of open/closes?

We will need to set a deadline for solving this before falling back to one of
the work-arounds.  RC1 certainly won't go out with this still in it, and I'd
prefer it earlier to confirm the work-around doesn't just move the problem
elsewhere.

Thanks!
Comment 29 David Hubner 2010-06-12 00:39:33 UTC
As far as I can see from the initial valgrind log and the valgrind log of this issue I attached is that they are separate. It looks as the initial one was fixed by upgrading glibc, the latter issue happens on glibc2.12 which is verified to solve the initial problem. 

The latter issue looks like something deleting something twice or deleting something that is not referenced. It happens from ~HolidayParserDriverPlan() as far as I can tell.
Comment 30 Christopher Neufeld 2010-06-12 01:17:15 UTC
Addressing the question in comment 28 "Are we sure the KHoliday crash is caused by the possible glibc bug in tzset()?"

The nasty thing about the tzset() bug was that it corrupted the malloc() freespace by free-ing something that had never come from malloc.  This does not necessarily result in an immediate crash.  Instead, things hum along nicely, mallocing and freeing, until some time later one of those operations causes things to explode because the memory allocator can't resolve its innards.  In the specific case I was watching, the eventual crash occurred under fclose() when the library was tearing down the FILE* object, but the damage had been done long before that.

My valgrinding with glibc-2.11 did not show this invalid free() call under the same conditions, with the same binaries.  This suggests that either the bug under tzset() was fixed, or that something in the new glibc setup modified the way tzset() runs behind the scenes in such a way as to avoid triggering the bug.

So, in my specific case (refer to my comments in bug 241122), upgrading the glibc made this problem go away.
Comment 31 John Layt 2010-06-12 02:29:49 UTC
I get the feeling David, Christopher and I are seeing 2 or 3 different bugs.

I've tried David's patch, but it doesn't resolve my instance of the crash as the rewind is happening on a yyin that has a value, just one that is now invalid as closed.  However it did lead me to put tracing on the yyin value to see what happens to it, and it is now clear that some kind of yyin confusion is happening.  Creating the plasmoid I'm seeing the original holiday file opened and rewound OK with the original yyin, then when the config dialog is displayed each file is read for its metadata resulting in a series of fopen/rewind/fclose on a new yyin value each time.  However once the config is closed the plasmoid tries to request new holidays from it's original HolidayRegion instance it doesn't try rewind the original yyin as it should, instead the last yyin from the metadata scan is used which has been closed.  The original yyin is never reported as closed.

So this has nothing directly to do with the calendar system change, it just forces a request for updated holidays, not changing anything and simply navigating to a new month triggers a new request and thus a crash as well.  Changing the holiday region doesn't trigger the crash as a new holiday region is created with a new valid yyin.  This also explains why my work-around of not caching the region solved the problem, as it forced a new yyin.

I'll press on in the morning trying to find why the wrong yyin is used.
Comment 32 Christopher Neufeld 2010-06-12 02:47:25 UTC
John:  as a general safety rule, and something that might show you where things are going wrong, I'd suggest setting yyin to NULL after it is closed.  Anybody who tries to read, rewind, or fclose on a NULL pointer should segfault immediately, and give you debugging clues in the backtrace.

Note that, contrary to a point raised in comment 27, there's no guarantee that rewind(NULL) will work.  In glibc-2.11, based on a quick glance at the code, it'll segfault.
Comment 33 David Hubner 2010-06-12 03:21:12 UTC
I managed to replicate the bug and squash it.. it comes down to FILE descriptors ( in fact the whole C fopen,fclose ) system not being c++ safe. 

Attached is a patch that fixes the problem
Comment 34 David Hubner 2010-06-12 03:22:19 UTC
Created attachment 47921 [details]
True KHols fix
Comment 35 Christopher Neufeld 2010-06-12 03:30:20 UTC
OK, I didn't like the first patch, which looked to be obscuring symptoms rather than fixing a bug.  The second patch looks OK to me.  Best would be if there were some way to ensure that yyin was invalid before scannerInitialise() and after scannerTerminate(), so that we're sure the lexer isn't churning away on nonsense.  I'd have a method that sets yyin to NULL, one that is called in the HolidayParserDriverPlan constructor, and also after fclose() in scannerTerminate().  Just my opinion, you're free to ignore it.
Comment 36 David Hubner 2010-06-12 03:40:08 UTC
More info in-case anyone is interested. 

What happens is that when you have a file open and are keeping it open, lets say the region you have set the calender to and then look for all the calenders available.. 

looking for all the calenders you open and close every file, closing the file the other task is using.. it does not like this. 

@Christopher Its better to have a controlled situation than a toggle check IMO :)
Comment 37 John Layt 2010-06-12 11:04:41 UTC
Thanks guys!  I was beginning to suspect the flex code was the problem.  Opening/closing the file each time the app requests holidays does seem a little inefficient, but at least the metadata is cached so it's not entirely pointless to keep the HolidayRegion cached.  I'll try work up a patch that allows us to keep the file open by storing the file pointer in a variable we control in a c++ safe way, but if that doesn't work I'll use David's with some validity checking baked in.
Comment 38 John Layt 2010-06-12 11:27:25 UTC
Root cause: while Bison is generating proper C++ code using the lalr1.cc template, Flex is only faking it, it's only C and not reentrant.  It seems it is possible to force flex to generate proper C++ that properly encapsulates the lexer state and is reentrant so I'll look at doing that.
Comment 39 David Hubner 2010-06-12 12:23:18 UTC
Pleasure, it was nice code to work with. :) Looking forward to using this in 4.5
Comment 40 Christopher Neufeld 2010-06-12 13:45:49 UTC
John:  I've written flex code for C++ with real objects.  You can create multiple classes each with its own scanner, and multiple instances of a class, each with its own input, unlike vanilla flex that puts its state into globals.

It's a bit involved to paste into a bugzilla entry.  I've got sample code if you'd like to go over it in email.  I've added your address to the whitelist of addresses allowed to send to my kdebugs email, which normally rejects as spam anything not coming from @kde.org.
Comment 41 John Layt 2010-06-12 14:12:12 UTC
Christopher:  Expert help would be most welcome :-)  I'm currently working off http://idlebox.net/2007/flex-bison-cpp-example/ which uses the FlexLexer.h class and std classes and streams, but if you have a more Qt-friendly example wrapping it that would be better.  We'll take this offline now while we work things out.
Comment 42 John Layt 2010-06-14 16:08:28 UTC
SVN commit 1137866 by jlayt:

Fix crasher in KHolidays where file descriptors were getting confused.

Done using two main changes:
1) Use Flex in C++ mode which makes the code fully re-entrant
2) Load the holiday file using QFile into a QByteArray so the file is not kept
   open.  This will increase memory usage, but save many file reads.

Note most of this is generated code, and also includes another standard header
from Flex.

Some improvements still to come, but this is a good baseline to tweak from.

Thanks to David and Christopher for their help in sorting this one out.

CCBUG: 210769



 A             FlexLexer.h   [License: GENERATED FILE]
 M  +20 -7     holidayparserdriverplan.cpp  
 M  +12 -17    holidayparserdriverplan_p.h  
 M  +104 -96   holidayparserplan.cpp  
 M  +7 -10     holidayparserplan.hpp  
 M  +49 -20    holidayparserplan.ypp  
 M  +522 -662  holidayscannerplan.cpp  
 M  +73 -19    holidayscannerplan.lpp  
 A             holidayscannerplan_p.h   [License: Public Domain LGPL (v2+)]


WebSVN link: http://websvn.kde.org/?view=rev&revision=1137866