Bug 315910

Summary: Memory leaks in the parser
Product: kdepimlibs Reporter: Eugene A. Shatokhin <eugene.shatokhin>
Component: kholidaysAssignee: John Layt <jlayt>
Status: RESOLVED FIXED    
Severity: normal CC: adaptee, kdepim-bugs, montel, winter
Priority: NOR    
Version: 4.9   
Target Milestone: ---   
Platform: Unlisted Binaries   
OS: Linux   
Latest Commit: Version Fixed In: 4.11
Attachments: The patch to fix the leaks

Description Eugene A. Shatokhin 2013-02-28 14:57:32 UTC
There are 2 groups of memory leaks in the parser plan2. Over time, they accumulate to a sizeable amount.

1.  kholidays/parsers/plan2/holidayscannerplan.lpp:102

Memory allocated for a string here (via strdup()) is never freed. The allocation happens in the following fragment:
--------------------------
\"[^"]*\"           { yylval->sval = strdup( yytext + 1 );
                      yylval->sval[ strlen( yylval->sval ) - 1 ] = 0;
                      return token::STRING; }
--------------------------

2. kholidays/parsers/plan2/holidayparserplan.ypp:72

Memory allocated for a string here is also never freed:
--------------------------
%initial-action
{
    // initialize the initial location object
    @$.begin.filename = new std::string( driver.filePath().toLocal8Bit().data() );
    @$.end.filename = @$.begin.filename;
};
--------------------------

Valgrind also detects these leaks, here are the extracts from its report:
--------------------------
==14386== 80,103 bytes in 3,259 blocks are definitely lost in loss record 32,797 of 32,838
==14386==    at 0x402A214: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==14386==    by 0x4139610: strdup (in /lib/i686/libc-2.15.so)
==14386==    by 0x109750F6: KHolidays::HolidayScannerPlan::lex(KHolidays::HolidayParserPlan::semantic_type*, KHolidays::location*) (/usr/src/debug/kdepimlibs-4.9.5/build/kholidays/holidayscannerplan.lpp:102)
==14386==    by 0x1097DEF2: KHolidays::HolidayParserPlan::parse() (/usr/src/debug/kdepimlibs-4.9.5/build/kholidays/holidayparserplan.cpp:323)
==14386==    by 0x10979F8D: KHolidays::HolidayParserDriverPlan::parseMetadata() (/usr/src/debug/kdepimlibs-4.9.5/kholidays/parsers/plan2/holidayparserdriverplan.cpp:132)
==14386==    by 0x1097A6AD: KHolidays::HolidayParserDriverPlan::HolidayParserDriverPlan(QString const&) (/usr/src/debug/kdepimlibs-4.9.5/kholidays/parsers/plan2/holidayparserdriverplan.cpp:67)
==14386==    by 0x1096BB13: KHolidays::HolidayRegion::Private::Private(QString const&) (/usr/src/debug/kdepimlibs-4.9.5/kholidays/holidayregion.cpp:82)
==14386==    by 0x1096A3E3: KHolidays::HolidayRegion::HolidayRegion(QString const&) (/usr/src/debug/kdepimlibs-4.9.5/kholidays/holidayregion.cpp:114)
==14386==    by 0x1096A611: KHolidays::HolidayRegion::countryCode(QString const&) (/usr/src/debug/kdepimlibs-4.9.5/kholidays/holidayregion.cpp:176)
==14386==    by 0x1096ABC4: KHolidays::HolidayRegion::defaultRegionCode(QString const&, QString const&) (/usr/src/debug/kdepimlibs-4.9.5/kholidays/holidayregion.cpp:437)
==14386==    by 0x17D7DC8C: CalendarEngine::holidayCalendarSourceRequest(QString const&, QStringList const&, QString const&) (/usr/src/debug/kde-workspace-4.9.5/plasma/generic/dataengines/calendar/calendarengine.cpp:121)
==14386==    by 0x17D81094: CalendarEngine::sourceRequestEvent(QString const&) (/usr/src/debug/kde-workspace-4.9.5/plasma/generic/dataengines/calendar/calendarengine.cpp:78)
==14386==    by 0x43779B4: Plasma::DataEnginePrivate::requestSource(QString const&, bool*) (/usr/src/debug/kdelibs-4.9.5/plasma/dataengine.cpp:707)
==14386==    by 0x4377AC0: Plasma::DataEngine::query(QString const&) const (/usr/src/debug/kdelibs-4.9.5/plasma/dataengine.cpp:136)
==14386==    by 0x10954646: Plasma::CalendarTablePrivate::defaultHolidaysRegion() (/usr/src/debug/kde-workspace-4.9.5/libs/plasmaclock/calendartable.cpp:317)
==14386==    by 0x1094CF40: Plasma::CalendarTable::applyConfiguration(KConfigGroup) (/usr/src/debug/kde-workspace-4.9.5/libs/plasmaclock/calendartable.cpp:887)
==14386==    by 0x109484F5: Plasma::Calendar::applyConfiguration(KConfigGroup) (/usr/src/debug/kde-workspace-4.9.5/libs/plasmaclock/calendar.cpp:384)
==14386==    by 0x109410B6: ClockApplet::configChanged() (/usr/src/debug/kde-workspace-4.9.5/libs/plasmaclock/clockapplet.cpp:459)
==14386==    by 0x1093C724: ClockApplet::init() (/usr/src/debug/kde-workspace-4.9.5/libs/plasmaclock/clockapplet.cpp:612)
==14386==    by 0x10907E7D: Clock::init() (/usr/src/debug/kde-workspace-4.9.5/plasma/generic/applets/digital-clock/clock.cpp:77)
==14386==    by 0x435AF36: Plasma::ContainmentPrivate::initApplets() (/usr/src/debug/kdelibs-4.9.5/plasma/containment.cpp:463)
==14386==    by 0x4370001: Plasma::CoronaPrivate::importLayout(KConfigBase const&, bool) (/usr/src/debug/kdelibs-4.9.5/plasma/corona.cpp:1067)
==14386==    by 0x4370D74: Plasma::Corona::loadLayout(QString const&) (/usr/src/debug/kdelibs-4.9.5/plasma/corona.cpp:278)
==14386==    by 0x4370E4D: Plasma::Corona::initializeLayout(QString const&) (/usr/src/debug/kdelibs-4.9.5/plasma/corona.cpp:181)
==14386==    by 0x4096E97: PlasmaApp::corona(bool) (/usr/src/debug/kde-workspace-4.9.5/plasma/desktop/shell/plasmaapp.cpp:850)
==14386==    by 0x409721B: PlasmaApp::setupDesktop() (/usr/src/debug/kde-workspace-4.9.5/plasma/desktop/shell/plasmaapp.cpp:312)
==14386==    by 0x4098978: PlasmaApp::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (/usr/src/debug/kde-workspace-4.9.5/build/plasma/desktop/shell/plasmaapp.moc:125)
==14386==    by 0x575F5B9: QMetaCallEvent::placeMetaCall(QObject*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x576429A: QObject::event(QEvent*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x574E169: QCoreApplication::event(QEvent*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x5A0CD40: QApplication::event(QEvent*) (in /usr/lib/libQtGui.so.4.8.4)
==14386==    by 0x5A0B6EB: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.8.4)
==14386==    by 0x5A0D71E: QApplication::notify(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.8.4)
==14386==    by 0x502BD00: KApplication::notify(QObject*, QEvent*) (/usr/src/debug/kdelibs-4.9.5/kdeui/kernel/kapplication.cpp:311)
==14386==    by 0x574DBBD: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x57516AF: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x5751A9B: QCoreApplication::sendPostedEvents(QObject*, int) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x577EDB3: postEventSourceDispatch(_GSource*, int (*)(void*), void*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x95108B2: g_main_context_dispatch (in /lib/libglib-2.0.so.0.3400.3)
==14386==    by 0x9510C4F: ??? (in /lib/libglib-2.0.so.0.3400.3)

==14386== 
==14386== 5,588 (336 direct, 5,252 indirect) bytes in 84 blocks are definitely lost in loss record 32,515 of 32,838
==14386==    at 0x4029CFA: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==14386==    by 0x1097C97D: KHolidays::HolidayParserPlan::parse() (/usr/src/debug/kdepimlibs-4.9.5/build/kholidays/holidayparserplan.ypp:72)
==14386==    by 0x10979F8D: KHolidays::HolidayParserDriverPlan::parseMetadata() (/usr/src/debug/kdepimlibs-4.9.5/kholidays/parsers/plan2/holidayparserdriverplan.cpp:132)
==14386==    by 0x1097A6AD: KHolidays::HolidayParserDriverPlan::HolidayParserDriverPlan(QString const&) (/usr/src/debug/kdepimlibs-4.9.5/kholidays/parsers/plan2/holidayparserdriverplan.cpp:67)
==14386==    by 0x1096BB13: KHolidays::HolidayRegion::Private::Private(QString const&) (/usr/src/debug/kdepimlibs-4.9.5/kholidays/holidayregion.cpp:82)
==14386==    by 0x1096A3E3: KHolidays::HolidayRegion::HolidayRegion(QString const&) (/usr/src/debug/kdepimlibs-4.9.5/kholidays/holidayregion.cpp:114)
==14386==    by 0x1096A591: KHolidays::HolidayRegion::languageCode(QString const&) (/usr/src/debug/kdepimlibs-4.9.5/kholidays/holidayregion.cpp:191)
==14386==    by 0x1096ACF4: KHolidays::HolidayRegion::defaultRegionCode(QString const&, QString const&) (/usr/src/debug/kdepimlibs-4.9.5/kholidays/holidayregion.cpp:442)
==14386==    by 0x17D7DC8C: CalendarEngine::holidayCalendarSourceRequest(QString const&, QStringList const&, QString const&) (/usr/src/debug/kde-workspace-4.9.5/plasma/generic/dataengines/calendar/calendarengine.cpp:121)
==14386==    by 0x17D81094: CalendarEngine::sourceRequestEvent(QString const&) (/usr/src/debug/kde-workspace-4.9.5/plasma/generic/dataengines/calendar/calendarengine.cpp:78)
==14386==    by 0x43779B4: Plasma::DataEnginePrivate::requestSource(QString const&, bool*) (/usr/src/debug/kdelibs-4.9.5/plasma/dataengine.cpp:707)
==14386==    by 0x4377AC0: Plasma::DataEngine::query(QString const&) const (/usr/src/debug/kdelibs-4.9.5/plasma/dataengine.cpp:136)
==14386==    by 0x10954646: Plasma::CalendarTablePrivate::defaultHolidaysRegion() (/usr/src/debug/kde-workspace-4.9.5/libs/plasmaclock/calendartable.cpp:317)
==14386==    by 0x1094CF40: Plasma::CalendarTable::applyConfiguration(KConfigGroup) (/usr/src/debug/kde-workspace-4.9.5/libs/plasmaclock/calendartable.cpp:887)
==14386==    by 0x109484F5: Plasma::Calendar::applyConfiguration(KConfigGroup) (/usr/src/debug/kde-workspace-4.9.5/libs/plasmaclock/calendar.cpp:384)
==14386==    by 0x109410B6: ClockApplet::configChanged() (/usr/src/debug/kde-workspace-4.9.5/libs/plasmaclock/clockapplet.cpp:459)
==14386==    by 0x1093C724: ClockApplet::init() (/usr/src/debug/kde-workspace-4.9.5/libs/plasmaclock/clockapplet.cpp:612)
==14386==    by 0x10907E7D: Clock::init() (/usr/src/debug/kde-workspace-4.9.5/plasma/generic/applets/digital-clock/clock.cpp:77)
==14386==    by 0x435AF36: Plasma::ContainmentPrivate::initApplets() (/usr/src/debug/kdelibs-4.9.5/plasma/containment.cpp:463)
==14386==    by 0x4370001: Plasma::CoronaPrivate::importLayout(KConfigBase const&, bool) (/usr/src/debug/kdelibs-4.9.5/plasma/corona.cpp:1067)
==14386==    by 0x4370D74: Plasma::Corona::loadLayout(QString const&) (/usr/src/debug/kdelibs-4.9.5/plasma/corona.cpp:278)
==14386==    by 0x4370E4D: Plasma::Corona::initializeLayout(QString const&) (/usr/src/debug/kdelibs-4.9.5/plasma/corona.cpp:181)
==14386==    by 0x4096E97: PlasmaApp::corona(bool) (/usr/src/debug/kde-workspace-4.9.5/plasma/desktop/shell/plasmaapp.cpp:850)
==14386==    by 0x409721B: PlasmaApp::setupDesktop() (/usr/src/debug/kde-workspace-4.9.5/plasma/desktop/shell/plasmaapp.cpp:312)
==14386==    by 0x4098978: PlasmaApp::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (/usr/src/debug/kde-workspace-4.9.5/build/plasma/desktop/shell/plasmaapp.moc:125)
==14386==    by 0x575F5B9: QMetaCallEvent::placeMetaCall(QObject*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x576429A: QObject::event(QEvent*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x574E169: QCoreApplication::event(QEvent*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x5A0CD40: QApplication::event(QEvent*) (in /usr/lib/libQtGui.so.4.8.4)
==14386==    by 0x5A0B6EB: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.8.4)
==14386==    by 0x5A0D71E: QApplication::notify(QObject*, QEvent*) (in /usr/lib/libQtGui.so.4.8.4)
==14386==    by 0x502BD00: KApplication::notify(QObject*, QEvent*) (/usr/src/debug/kdelibs-4.9.5/kdeui/kernel/kapplication.cpp:311)
==14386==    by 0x574DBBD: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x57516AF: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x5751A9B: QCoreApplication::sendPostedEvents(QObject*, int) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x577EDB3: postEventSourceDispatch(_GSource*, int (*)(void*), void*) (in /usr/lib/libQtCore.so.4.8.4)
==14386==    by 0x95108B2: g_main_context_dispatch (in /lib/libglib-2.0.so.0.3400.3)
==14386==    by 0x9510C4F: ??? (in /lib/libglib-2.0.so.0.3400.3)
==14386==    by 0x9510D30: g_main_context_iteration (in /lib/libglib-2.0.so.0.3400.3)
==14386==    by 0x577EF37: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/lib/libQtCore.so.4.8.4)
--------------------------


Reproducible: Always




OS: ROSA Desktop Fresh 2012 x86-64
KDE: 4.9.5
Qt: 4.8.4
Comment 1 Eugene A. Shatokhin 2013-02-28 15:02:01 UTC
As far as I can see in the source code of KHolidays in git repo, the problem affects the current version as well.
Comment 2 Eugene A. Shatokhin 2013-03-04 12:32:49 UTC
Created attachment 77737 [details]
The patch to fix the leaks

I have finally come up with the patch to fix these leaks. It may be not the best way but it works for me.
Comment 3 Laurent Montel 2013-03-04 12:51:32 UTC
Better to put in reviewbord but ok.
For me :
std::string *fileToParse() seem logical. Perhaps add a "const"; => std::string *fileToParse() const;

For other mem leak your fix seems good (but I didn't test it).

For yacc language I don't know I don't know syntax

but for me your patch seems good.
Comment 4 Allen Winter 2013-03-16 19:01:12 UTC
Thanks for the patch Eugene.  I will review it and commit as needed.  First look seems ok.
Comment 5 Allen Winter 2013-06-22 15:26:42 UTC
Git commit 98eae3ab66e30ea6469a7593a7ed8fbc4d717f3e by Allen Winter.
Committed on 22/06/2013 at 15:24.
Pushed by winterz into branch 'master'.

Plug 2 groups of memory leaks in the parser plan2.

Thanks for the patch Eugene!
FIXED-IN: 4.11

M  +6    -0    kholidays/parsers/plan2/holidayparserdriverplan.cpp
M  +4    -0    kholidays/parsers/plan2/holidayparserdriverplan_p.h
M  +40   -8    kholidays/parsers/plan2/holidayparserplan.cpp
M  +9    -7    kholidays/parsers/plan2/holidayparserplan.ypp

http://commits.kde.org/kdepimlibs/98eae3ab66e30ea6469a7593a7ed8fbc4d717f3e