Control: tags -1 + patch
Dear Maintainer, I tried to have a look and found something. This issue might be in the package since poppler-0.71.patch. This patch makes some changes how containers get accessed. Following I found and tried to change in attached patch: - std::erase, std::clear, std::remove: These methods of STL containers containing pointer to objects do not delete the objects pointed to. - In continuousView in PDFCore::addPage the next page was inserted at the first position. For running with valgrind it was nice to have the additional cflag HAVE_XTAPPSETEXITFLAG set, as then the application cleans up instead of just exit(0). Bug #942086 and #926501 might be related. Kind regards, Bernhard
# Unstable amd64 qemu VM 2019-11-21 apt update apt dist-upgrade apt install dpkg-dev devscripts quilt systemd-coredump xserver-xorg lightdm openbox xterm htop mc gdb valgrind heaptrack heaptrack-gui pari-doc xpdf xpdf-dbgsym libfreetype6-dbgsym libpoppler82-dbgsym apt build-dep xpdf mkdir /home/benutzer/source/xpdf/orig -p cd /home/benutzer/source/xpdf/orig apt source xpdf cd mkdir /home/benutzer/source/libpoppler82/orig -p cd /home/benutzer/source/libpoppler82/orig apt source libpoppler82 cd export LANG=C export DISPLAY=:0 /usr/bin/xpdf.real /usr/share/pari/doc/users.pdf # ~10 times next page and previous page - memory usage doubles. ########## # wget https://github.com/WuBingzheng/memleax/releases/download/v1.1.1/memleax_1.1.1-1_amd64.deb # dpkg -i memleax_1.1.1-1_amd64.deb # memleax $(pidof xpdf.real) # gdb -q --args xpdf.real /usr/share/pari/doc/users.pdf # Reading symbols from /usr/lib/debug/.build-id/ab/a6d385be8071a6a44247a89331bee9f0494091.debug... # memleax -d /usr/lib/debug/.build-id/ab/a6d385be8071a6a44247a89331bee9f0494091.debug $(pidof xpdf.real) # Had no output at all. ########## script -a valgrind-xpdf.real_$(date +%Y-%m-%d_%H-%M-%S).txt -c 'valgrind /usr/bin/xpdf.real /usr/share/pari/doc/users.pdf' script -a valgrind-xpdf.real_$(date +%Y-%m-%d_%H-%M-%S).txt -c 'valgrind --leak-check=full --show-reachable=yes --leak-resolution=high --num-callers=100 --trace-children=yes /usr/bin/xpdf.real /usr/share/pari/doc/users.pdf' ==35071== 34,438,272 bytes in 11 blocks are possibly lost in loss record 1,608 of 1,608 ==35071== at 0x483577F: malloc (vg_replace_malloc.c:309) ==35071== by 0x11F82C: gmalloc (gmem.h:41) ==35071== by 0x11F82C: gmallocn (gmem.h:115) ==35071== by 0x11F82C: XPDFCore::updateTileData(PDFCoreTile*, int, int, int, int, bool) (XPDFCore.cc:1276) ==35071== by 0x119C5C: PDFCore::clippedRedrawRect(PDFCoreTile*, int, int, int, int, int, int, int, int, int, int, bool, bool) (PDFCore.cc:2171) ==35071== by 0x119D5F: PDFCore::redrawCbk(void*, int, int, int, int, bool) (PDFCore.cc:2068) ==35071== by 0x1166F5: dump (CoreOutputDev.cc:53) ==35071== by 0x1166F5: CoreOutputDev::dump() (CoreOutputDev.cc:46) ==35071== by 0x4E6016F: Gfx::go(bool) (Gfx.cc:827) ==35071== by 0x4E6049D: Gfx::display(Object*, bool) (Gfx.cc:714) ==35071== by 0x4EB6940: Page::displaySlice(OutputDev*, double, double, int, bool, bool, int, int, int, int, bool, bool (*)(void*), void*, bool (*)(Annot*, void*), void*, bool) (Page.cc:548) ==35071== by 0x11AD82: PDFCore::needTile(PDFCorePage*, int, int) (PDFCore.cc:924) ==35071== by 0x11BBB0: PDFCore::update(int, int, int, double, int, bool, bool, bool) (PDFCore.cc:724) ==35071== by 0x122380: XPDFCore::update(int, int, int, double, int, bool, bool, bool) (XPDFCore.cc:297) ==35071== by 0x11734E: gotoNextPage (PDFCore.cc:963) ==35071== by 0x11734E: PDFCore::gotoNextPage(int, bool) (PDFCore.cc:947) ==35071== by 0x1223E1: XPDFCore::gotoNextPage(int, bool) (XPDFCore.cc:325) ==35071== by 0x127937: XPDFViewer::nextPageCbk(_WidgetRec*, void*, void*) (XPDFViewer.cc:2451) ==35071== by 0x49361BA: ??? (in /usr/lib/x86_64-linux-gnu/libXm.so.4.0.4) ==35071== by 0x505F4DE: ??? (in /usr/lib/x86_64-linux-gnu/libXt.so.6.0.0) ==35071== by 0x5060552: _XtTranslateEvent (in /usr/lib/x86_64-linux-gnu/libXt.so.6.0.0) ==35071== by 0x5038479: XtDispatchEventToWidget (in /usr/lib/x86_64-linux-gnu/libXt.so.6.0.0) ==35071== by 0x5038ED1: ??? (in /usr/lib/x86_64-linux-gnu/libXt.so.6.0.0) ==35071== by 0x5039030: XtDispatchEvent (in /usr/lib/x86_64-linux-gnu/libXt.so.6.0.0) ==35071== by 0x5044CFF: XtAppProcessEvent (in /usr/lib/x86_64-linux-gnu/libXt.so.6.0.0) ==35071== by 0x503944C: XtAppMainLoop (in /usr/lib/x86_64-linux-gnu/libXt.so.6.0.0) ==35071== by 0x11626C: main (xpdf.cc:310) gdb -q --args /usr/bin/xpdf.real /usr/share/pari/doc/users.pdf set width 0 set pagination off directory /home/benutzer/source/xpdf/orig/xpdf-3.04/xpdf directory /home/benutzer/source/libpoppler82/orig/poppler-0.71.0 b CoreOutputDev::CoreOutputDev y run ############### try1: debian/rules HAVE_XTAPPSETEXITFLAG --> XPDFApp::~XPDFApp get now reached xpdf/XPDFApp.cc void XPDFApp::quit() { if (remoteAtom != None) { XSetSelectionOwner(display, remoteAtom, None, CurrentTime); } for (auto ptr : *viewers) { delete static_cast<XPDFViewer*>(ptr); } viewers->clear(); -> clear of a std::vector of pointer to type does not call the destructor on the type pointed to b XPDFViewer::~XPDFViewer b XPDFApp::~XPDFApp b XPDFApp::quit gdb -q --args /usr/bin/xpdf.real /usr/share/pari/doc/users.pdf set width 0 set pagination off directory /home/benutzer/source/xpdf/try1/xpdf-3.04/xpdf directory /home/benutzer/source/libpoppler82/orig/poppler-0.71.0 b XPDFCore::updateTileData run ########## benutzer@debian:~$ heaptrack /usr/bin/xpdf.real /usr/share/pari/doc/users.pdf heaptrack output will be written to "/home/benutzer/heaptrack.xpdf.real.1182.gz" starting application, this might take some time... free(): invalid pointer Aborted (core dumped) heaptrack stats: allocations: 2445627 leaked allocations: 496282 temporary allocations: 231256 Heaptrack finished! Now run the following to investigate the data: heaptrack --analyze "/home/benutzer/heaptrack.xpdf.real.1182.gz" benutzer@debian:~$ script -a heaptrack-xpdf.real.1182.txt -c 'heaptrack --analyze "/home/benutzer/heaptrack.xpdf.real.1182.gz"' gdb -q --args /usr/bin/xpdf.real /usr/share/pari/doc/users.pdf set width 0 set pagination off b FT_Load_Glyph y run
Description: Update poppler-0.71.patch Change some accesses to containers to avoid memory leaks. Author: Bernhard Ãbelacker <bernha...@mailbox.org> Bug-Debian: https://bugs.debian.org/945188 Forwarded: no Last-Update: 2019-11-21 --- xpdf-3.04.orig/xpdf/GlobalParams.cc +++ xpdf-3.04/xpdf/GlobalParams.cc @@ -1671,6 +1671,7 @@ void GlobalParams::parseBind(GList *toke if (binding->code == code && binding->mods == mods && binding->context == context) { + delete static_cast<KeyBinding*>(*it); keyBindings->erase(it); break; } @@ -1701,6 +1702,7 @@ void GlobalParams::parseUnbind(GList *to if (binding->code == code && binding->mods == mods && binding->context == context) { + delete static_cast<KeyBinding*>(*it); keyBindings->erase(it); break; } --- xpdf-3.04.orig/xpdf/PDFCore.cc +++ xpdf-3.04/xpdf/PDFCore.cc @@ -208,6 +208,7 @@ int PDFCore::loadFile2(PDFDoc *newDoc) { // nothing displayed yet topPage = -99; midPage = -99; + for (auto ptr : *pages) { delete static_cast<PDFCorePage*>(ptr); } pages->clear(); // compute the max unscaled page size @@ -242,6 +243,7 @@ void PDFCore::clear() { // no page displayed topPage = -99; midPage = -99; + for (auto ptr : *pages) { delete static_cast<PDFCorePage*>(ptr); } pages->clear(); // redraw @@ -265,6 +267,7 @@ PDFDoc *PDFCore::takeDoc(GBool redraw) { // no page displayed topPage = -99; midPage = -99; + for (auto ptr : *pages) { delete static_cast<PDFCorePage*>(ptr); } pages->clear(); // redraw @@ -485,6 +488,7 @@ void PDFCore::update(int topPageA, int s rotateA != rotate) { needUpdate = gTrue; setSelection(0, 0, 0, 0, 0); + for (auto ptr : *pages) { delete static_cast<PDFCorePage*>(ptr); } pages->clear(); zoom = zoomA; rotate = rotateA; @@ -607,17 +611,12 @@ void PDFCore::update(int topPageA, int s // objects that are needed for (auto it = pages->begin(); it != pages->end();) { auto page = static_cast<PDFCorePage *> (*it); - if (page->page >= pg0) - break; - it = pages->erase(it); - } - - for (auto it = pages->rbegin(); it != pages->rend();) { - auto page = static_cast<PDFCorePage *> (*it); - if (page->page <= pg1) - break; - - it = decltype(it){ pages->erase(std::next(it).base()) }; + if (page->page >= pg0 && page->page <=pg1) { + it++; + } else { + delete static_cast<PDFCorePage*>(*it); + it = pages->erase(it); + } } j = pages->getLength() > 0 ? ((PDFCorePage *)pages->get(0))->page - 1 @@ -663,6 +662,7 @@ void PDFCore::update(int topPageA, int s tile->xMin > scrollX + drawAreaWidth + drawAreaWidth / 2 || y1 < scrollY - drawAreaHeight / 2 || y0 > scrollY + drawAreaHeight + drawAreaHeight / 2) { + delete static_cast<PDFCoreTile*>(*itt); itt = page->tiles->erase(itt); } else { itt++; @@ -839,7 +839,7 @@ void PDFCore::addPage(int pg, int rot) { } } - pages->insert(pages->begin(), page); + pages->push_back(page); } void PDFCore::needTile(PDFCorePage *page, int x, int y) { --- xpdf-3.04.orig/xpdf/XPDFApp.cc +++ xpdf-3.04/xpdf/XPDFApp.cc @@ -265,9 +265,9 @@ XPDFViewer *XPDFApp::openAtDest(GString XPDFViewer *XPDFApp::reopen(XPDFViewer *viewer, PDFDoc *doc, int page, GBool fullScreenA) { - int i; - viewers->erase(std::remove(viewers->begin(), viewers->end(), viewer), viewers->end()); + std::remove(viewers->begin(), viewers->end(), viewer); + delete viewer; viewer = new XPDFViewer(this, doc, page, NULL, fullScreenA); if (!viewer->isOk()) { @@ -295,12 +295,15 @@ void XPDFApp::close(XPDFViewer *viewer, if (closeLast) { quit(); } else { + for (auto ptr : *viewers) { delete static_cast<XPDFViewer*>(ptr); } viewer->clear(); } } else { for (i = 0; i < viewers->getLength(); ++i) { if (((XPDFViewer *)viewers->get(i)) == viewer) { - viewers->erase(viewers->begin() + i); + auto it = viewers->begin() + i; + delete static_cast<XPDFViewer*>(*it); + viewers->erase(it); if (remoteAtom != None && remoteViewer == viewer) { remoteViewer = (XPDFViewer *)viewers->get(viewers->getLength() - 1); remoteWin = remoteViewer->getWindow(); @@ -318,6 +321,7 @@ void XPDFApp::quit() { if (remoteAtom != None) { XSetSelectionOwner(display, remoteAtom, None, CurrentTime); } + for (auto ptr : *viewers) { delete static_cast<XPDFViewer*>(ptr); } viewers->clear(); #if HAVE_XTAPPSETEXITFLAG XtAppSetExitFlag(appContext);