Details
-
Bug
-
Resolution: Out of scope
-
P3: Somewhat important
-
None
-
5.9.1
-
None
Description
The following code using QXmlQuery::evaluateTo(QString *output) leaks memory.
See the attached Leaks trace leaks_10rep.trace.zip generated using the Leaks utility of Apple's Instruments app. To reproduce it:
- First compile the qtbug project. (I used release mode)
- Open Apple's Instruments app.
- On the top choose the compiled app, i.e. qtbug.app.
- Choose the Leaks utility.
- Before starting, click on Leak Checks and then on snapshots on the bottom. Choose 1 second as interval here.
- Now start the recording using the record button and wait until the record button is visible again indicating that the trace is complete.
- Click on Leak Checks to see the table of leaks.
- For higher repetitions make sure to increase the waiting time at the end of the main function otherwise it will not capture all the leaks (ideally the Leaks utility shows a "No new leaks" indicator in the time line)
Alternatively, just use a high number of repetitions and uncomment the stop() at the end of the main method and then watch the Activity Monitor / Task Manager. About 1MB is leaked per 4 repetitions, so using 400 repetitions makes the app consume about 100MB when stopping.
See also attachment qtbug70710.zip for a working example with a Qt project file using the same code as below.
This leak might be related to QTBUG-20830, QTBUG-3628, QTBUG-60172, QTBUG-20802,
#include <iostream> #include <thread> #include <chrono> #include <QtCore> #include <QXmlQuery> namespace { constexpr int bytesOfOneMB = 1024*1024; void wasteMemory(const int megaBytes) { qInfo("Wasting %d MB now...", megaBytes); const int arraysize = megaBytes*bytesOfOneMB; char* array = new char[arraysize]; for(int i=0 ; i<arraysize; ++i) { array[i] = 'a'; } // delete [] array; // omitted to deliberately waste memory qInfo("Done"); } const QString xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n""\n" "<root>\n""\n" " <term>-1460087571.6437266</term>\n""\n" " <system>minerals</system>\n""\n" " <pot>become</pot>\n""\n" " <bet>1014767728</bet>\n""\n" " <rise>weight</rise>\n""\n" " <excitement>beneath</excitement>\n""\n" " <fast>1606330302.0943468</fast>\n""\n" " <serious>success</serious>\n""\n" " <band>56689147.3003366</band>\n""\n" " <room>order</room>\n""\n" " <difficult>-1846389049.7374732</difficult>\n""\n" " <slabs>1080777107</slabs>\n""\n" " <mile>-1429668644</mile>\n""\n" " <fireplace>-883024560</fireplace>\n""\n" " <exact>desk</exact>\n""\n" " <church>-516291204.614336</church>\n""\n" " <disappear>gift</disappear>\n""\n" " <song>2128439922</song>\n""\n" " <day>2076698251.2718477</day>\n""\n" " <library>1169567673.2849774</library>\n""\n" " <strong>slept</strong>\n""\n" " <factory>friendly</factory>\n""\n" " <broke>1704619180</broke>\n""\n" " <broken>arrow</broken>\n""\n" " <review>tank</review>\n""\n" " <idea>image</idea>\n""\n" " <successful>arrange</successful>\n""\n" " <barn>sheet</barn>\n""\n" " <sat>frame</sat>\n""\n" " <bar>-995623517.5095413</bar>\n""\n" " <different>-827945576.2976611</different>\n""\n" " <saddle>vertical</saddle>\n""\n" " <country>-1294579480</country>\n""\n" " <fine>-210237458.06976008</fine>\n""\n" " <people>shot</people>\n""\n" " <enemy>beneath</enemy>\n""\n" " <lose>wash</lose>\n""\n" " <left>nodded</left>\n""\n" " <underline>302480069</underline>\n""\n" " <journey>349298609.9499917</journey>\n""\n" " <two>855233261</two>\n""\n" " <throughout>policeman</throughout>\n""\n" " <safety>1101445487</safety>\n""\n" " <path>783122588.9262781</path>\n""\n" " <excited>-636194430</excited>\n""\n" " <line>mean</line>\n""\n" " <steam>908359265.9153657</steam>\n""\n" " <gone>-712892793.1713428</gone>\n""\n" " <pitch>684788275</pitch>\n""\n" " <close>-806401825.7013865</close>\n""\n" "</root>\n"; const QString xslt = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" "<xsl:stylesheet version=\"2.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" " <xsl:output method=\"xml\" encoding=\"utf-8\" indent=\"yes\" omit-xml-declaration=\"no\"/>\n" " <xsl:template match=\"@* | node()\">\n" " <xsl:copy>\n" " <xsl:apply-templates select=\"@* | node()\"/>\n" " </xsl:copy>\n" " </xsl:template>\n" "</xsl:stylesheet>\n"; void testXmlQuery(const int repetitions) { qInfo("Testing QXmlQuery now..."); QXmlQuery xmlQuery(QXmlQuery::XSLT20); xmlQuery.setFocus(xml); xmlQuery.setQuery(xslt); for ( int i = 0; i < repetitions; i++ ) { QString resString; // The following line seems to leak memory. Comment it out to confirm. xmlQuery.evaluateTo(&resString); } qInfo("Done"); } void stop() { qInfo("Stopping..."); std::cin.ignore(); } } // namespace int main(int argc, char **argv) { QCoreApplication ca(argc, argv); // wasteMemory(100); testXmlQuery(4); // leaks about 1MB per 4 repetitions // stop(); std::this_thread::sleep_for(std::chrono::seconds(5)); return 0; }