February 25, 2012

ib_sh ib_sh
Lab Rat
11 posts

Crash when running an XQuery via QtConcurrent::run

 

Hi all,

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:

  1. QList<QUrl> ExternalPlaylist::readTraktorLibraryPlaylist(const QString& playlistName, const Preferences& prefs){
  2.   QMutexLocker locker(&externalPlaylistMutex);
  3.   QStringList resultStrings;
  4.   QList<QUrl> results;
  5.  
  6.   QFile xmlFile(prefs.getTraktorLibraryPath());
  7.   if (!xmlFile.open(QIODevice::ReadOnly))
  8.     return results;
  9.  
  10.   QXmlQuery xmlQuery;
  11.   xmlQuery.bindVariable("inputDocument", &xmlFile);
  12.   xmlQuery.bindVariable("playlistName", QVariant(playlistName));
  13.  
  14.   QString xPath;
  15.   xPath += "doc($inputDocument)//NODE[@TYPE='PLAYLIST' and @NAME=($playlistName)]";
  16.   xPath += "/PLAYLIST[@TYPE='LIST']/ENTRY/PRIMARYKEY/@KEY/string(.)";
  17.  
  18.   xmlQuery.setQuery(xPath);
  19.   if(xmlQuery.evaluateTo(&resultStrings))
  20.     for(int i=0; i<(signed)resultStrings.size(); i++)
  21.       results.push_back(fixTraktorAddressing(resultStrings[i]));
  22.  
  23.   xmlFile.close();
  24.   return results;
  25. }

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:

  1.   xPath += "let $d := doc($inputDocument)/plist/dict ";
  2.   xPath += "for $track in $d/array[preceding-sibling::key[1]='Playlists']";
  3.   xPath += "/dict[child::string[preceding-sibling::key[1]='Name'][1]=($playlistName)]";
  4.   xPath += "/array/dict/integer[preceding-sibling::key[1]='Track ID'] ";
  5.   xPath += "return $d/dict[preceding-sibling::key[1]='Tracks']";
  6.   xPath += "/dict[preceding-sibling::key[1]=$track]";
  7.   xPath += "/string[preceding-sibling::key[1]='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.

  1. Thread 4 Crashed:
  2. 0   libsystem_c.dylib              0x00007fff930a3c19 szone_malloc_should_clear + 102
  3. 1   libsystem_c.dylib              0x00007fff930d93c8 malloc_zone_malloc + 77
  4. 2   libsystem_c.dylib              0x00007fff930da1a4 malloc + 44
  5. 3   libstdc++.6.dylib              0x00007fff887c168e operator new(unsigned long) + 94
  6. 4   QtXmlPatterns                  0x00000001010778d4 QPatternist::AccelTree::iterate(QXmlNodeModelIndex const&, QXmlNodeModelIndex::Axis) const + 2704
  7. 5   QtXmlPatterns                  0x00000001010cb4ab QPatternist::AxisStep::evaluateSequence(QExplicitlySharedDataPointer<QPatternist::DynamicContext> const&) const + 265
  8. 6   QtXmlPatterns                  0x00000001010e2352 QPatternist::FirstItemPredicate::evaluateSingleton(QExplicitlySharedDataPointer<QPatternist::DynamicContext> const&) const + 26
  9. 7   QtXmlPatterns                  0x000000010115004c QPatternist::Atomizer::evaluateSingleton(QExplicitlySharedDataPointer<QPatternist::DynamicContext> const&) const + 26
  10. 8   QtXmlPatterns                  0x0000000101100773 QPatternist::ValueComparison::evaluateSingleton(QExplicitlySharedDataPointer<QPatternist::DynamicContext> const&) const + 39
  11. 9   QtXmlPatterns                  0x00000001010d920a QPatternist::Expression::evaluateSequence(QExplicitlySharedDataPointer<QPatternist::DynamicContext> const&) const + 22
  12. 10  QtXmlPatterns                  0x00000001010e8887 QPatternist::GenericPredicate::mapToItem(QPatternist::Item const&, QExplicitlySharedDataPointer<QPatternist::DynamicContext> const&) const + 53
  13. 11  QtXmlPatterns                  0x00000001010e83f8 QPatternist::ItemMappingIterator<QPatternist::Item, QPatternist::Item, QExplicitlySharedDataPointer<QPatternist::GenericPredicate const>, QExplicitlySharedDataPointer<QPatternist::DynamicContext> >::next() + 148
  14. 12  QtXmlPatterns                  0x00000001010e8489 QPatternist::ItemMappingIterator<QPatternist::Item, QPatternist::Item, QExplicitlySharedDataPointer<QPatternist::GenericPredicate const>, QExplicitlySharedDataPointer<QPatternist::DynamicContext> >::next() + 293
  15. 13  QtXmlPatterns                  0x00000001010e8489 QPatternist::ItemMappingIterator<QPatternist::Item, QPatternist::Item, QExplicitlySharedDataPointer<QPatternist::GenericPredicate const>, QExplicitlySharedDataPointer<QPatternist::DynamicContext> >::next() + 293
  16. 14  QtXmlPatterns                  0x00000001010e8489 QPatternist::ItemMappingIterator<QPatternist::Item, QPatternist::Item, QExplicitlySharedDataPointer<QPatternist::GenericPredicate const>, QExplicitlySharedDataPointer<QPatternist::DynamicContext> >::next() + 293

Any help appreciated. Thanks.

2 replies

February 29, 2012

ib_sh ib_sh
Lab Rat
11 posts

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?

Cheers

March 4, 2012

ib_sh ib_sh
Lab Rat
11 posts

Couldn’t recreate this on Windows so perhaps it’s Mac only. Will try and test it on a pre-Lion Mac to narrow it down further.

(Sorry, I know I seem to be basically using this thread as a notepad now, but hopefully I’ll be able to cobble together enough info for a bug report at least).

 
  ‹‹ QPushButton don’t show background image in other windows pc      [SOLVED] Strange problem with resource file ››

You must log in to post a reply. Not a member yet? Register here!