-
Bug
-
Resolution: Out of scope
-
P3: Somewhat important
-
None
-
5.9.1
-
None
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;
}