Crash when running an XQuery via QtConcurrent::run
I have a couple of XQueries to read XML music libraries in two different formats. Both the routines are static, and they take roughly the same form:
- QMutexLocker locker(&externalPlaylistMutex);
- QStringList resultStrings;
- QFile xmlFile(prefs.getTraktorLibraryPath());
- if (!xmlFile.open(QIODevice::ReadOnly))
- return results;
- QXmlQuery xmlQuery;
- xmlQuery.bindVariable("inputDocument", &xmlFile);
- xmlQuery.bindVariable("playlistName", QVariant(playlistName));
- QString xPath;
- xPath += "doc($inputDocument)//NODE[@TYPE='PLAYLIST' and @NAME=($playlistName)]";
- xPath += "/PLAYLIST[@TYPE='LIST']/ENTRY/PRIMARYKEY/@KEY/string(.)";
- for(int i=0; i<(signed)resultStrings.size(); i++)
- return results;
That function works absolutely fine, whether it’s run in the GUI thread or via QtConcurrent::run. Its sibling is basically the same except for the XQuery string:
- xPath += "let $d := doc($inputDocument)/plist/dict ";
- xPath += "for $track in $d/array[preceding-sibling::key='Playlists']";
- xPath += "/dict[child::string[preceding-sibling::key='Name']=($playlistName)]";
- xPath += "/array/dict/integer[preceding-sibling::key='Track ID'] ";
- xPath += "return $d/dict[preceding-sibling::key='Tracks']";
- xPath += "/dict[preceding-sibling::key=$track]";
- xPath += "/string[preceding-sibling::key='Location']/string(text())";
… only this time, it works fine in the GUI thread but when run via QtConcurrent::run, it crashes while attempting xmlQuery.evaluateTo(&resultStrings), with EXC_BAD_ACCESS (SIGBUS). Now, obviously, this query is a lot more complex (it’s for parsing the iTunes library) and is much less efficient, running in something like quadratic time rather than linear. But it’s obviously functional, or it wouldn’t run in the GUI thread. This makes me think there must be something wrong with the surrounding function; something I’m missing with regard to QtConcurrent compatibility. Does anyone have any ideas?
I’ve pasted the crash log below; the last row is repeated literally hundreds of times in the error report but I’ve snipped it here.
- Thread 4 Crashed:
- 0 libsystem_c.dylib 0x00007fff930a3c19 szone_malloc_should_clear + 102
- 1 libsystem_c.dylib 0x00007fff930d93c8 malloc_zone_malloc + 77
- 2 libsystem_c.dylib 0x00007fff930da1a4 malloc + 44
- 3 libstdc++.6.dylib 0x00007fff887c168e operator new(unsigned long) + 94
Any help appreciated. Thanks.
Truly, this is a pain. I’ve just tested this code on Qt 4.8.0 (having been using 4.7.4 thus far) and the problem is still present.
I also tried a variant running the XQuery in another QThread but it was even less stable; any XQuery at all was segfaulting.
Anyone have any ideas? Or does anyone have any examples of a recursive QXmlQuery working outside the GUI thread?