Description
Some time ago, I implemented a module to export assets and metadata from Sketch-files.
Disclaimer: Unfortunately, I haven't managed to strip down the code to some minimal version yet. And for you, it might be a bit challenging to reproduce a bug since Sketch is a paid app (but with trial period) and availalbe only for macOS.
But I'll leave all the clues here at least for future self.
Steps to reproduce
- Clone a repo
git clone -b bug/QBS-1751 https://github.com/GooRoo/qbs-sketch.git
or
git clone -b bug/QBS-1751 git@github.com:GooRoo/qbs-sketch.git
- Run this in the repo:
qbs install --install-root .
This takes the logo/logo.sketch to produce some docs/assets/*.png-files via sketchtool.
Actual result
From time to time, I get an output like this:
❯ qbs install --install-root . Build graph does not yet exist for configuration 'default'. Starting from scratch. Resolving project for configuration default Setting up build graph for configuration default Building for configuration default [1] 87035 segmentation fault qbs install --install-root .
But sometimes it passes just okay. In this case you'll have to clean the build directory as the module won't re-export anything without the need.
If I run it in verbose mode, the last lines from the log look as following:
Building for configuration default qbs.exec: adding leaf RULE [sketch.metadata][sketch] [logo] located at /Users/me/Work/Projects/Personal/qbs-sketch/modules/Sketch/metadata/metadata.qbs:45:93 qbs.exec: adding leaf RULE [sketch.export-list][sketch] [logo] located at /Users/me/Work/Projects/Personal/qbs-sketch/modules/Sketch/export/export.qbs:70:93 qbs.buildgraph: consider rule node [sketch.metadata][sketch] changed: [] compatible: [/Users/me/Work/Projects/Personal/qbs-sketch/logo/logo.sketch] added: [/Users/me/Work/Projects/Personal/qbs-sketch/logo/logo.sketch] removed: [] qbs.buildgraph: Marking build graph as dirty [1] 78485 segmentation fault qbs install -vv --install-root .
The crash dump contains this:
Thread 3 Crashed:: QThread 0 libqbscore.2.0.2.dylib 0x100d00b48 JS_GetOwnPropertyNamesInternal + 76 1 libqbscore.2.0.2.dylib 0x100cd2504 qbs::Internal::handleJsProperties(JSContext*, JSValue, std::__1::function<void (unsigned int const&, JSPropertyDescriptor const&)> const&) + 96 2 libqbscore.2.0.2.dylib 0x100cd2504 qbs::Internal::handleJsProperties(JSContext*, JSValue, std::__1::function<void (unsigned int const&, JSPropertyDescriptor const&)> const&) + 96 3 libqbscore.2.0.2.dylib 0x100c897d4 qbs::Internal::ScriptEngine::observeImport(JSValue&) + 108 4 libqbscore.2.0.2.dylib 0x100c88ef0 qbs::Internal::ScriptEngine::Importer::run() + 96 5 libqbscore.2.0.2.dylib 0x100c88e60 qbs::Internal::ScriptEngine::import(std::__1::shared_ptr<qbs::Internal::FileContextBase const> const&, JSValue&, qbs::Internal::ObserveMode) + 48 6 libqbscore.2.0.2.dylib 0x100b3cf8c qbs::Internal::setupScriptEngineForFile(qbs::Internal::ScriptEngine*, std::__1::shared_ptr<qbs::Internal::FileContextBase const> const&, JSValue, qbs::Internal::ObserveMode const&) + 40 7 libqbscore.2.0.2.dylib 0x100b9f5f8 qbs::Internal::RulesApplicator::applyRule(qbs::Internal::RuleNode*, qbs::Internal::Set<qbs::Internal::Artifact*> const&, qbs::Internal::Set<qbs::Internal::Artifact*> const&) + 600 8 libqbscore.2.0.2.dylib 0x100b9d63c qbs::Internal::RuleNode::apply(qbs::Internal::Logger const&, std::__1::unordered_map<QString, qbs::Internal::ResolvedProduct const*, std::__1::hash<QString>, std::__1::equal_to<QString>, std::__1::allocator<std::__1::pair<QString const, qbs::Internal::ResolvedProduct const*> > > const&, std::__1::unordered_map<QString, qbs::Internal::ResolvedProject const*, std::__1::hash<QString>, std::__1::equal_to<QString>, std::__1::allocator<std::__1::pair<QString const, qbs::Internal::ResolvedProject const*> > > const&, qbs::Internal::RuleNode::ApplicationResult*) + 2712 9 libqbscore.2.0.2.dylib 0x100b6631c qbs::Internal::Executor::executeRuleNode(qbs::Internal::RuleNode*) + 140 10 libqbscore.2.0.2.dylib 0x100b6a718 qbs::Internal::Executor::visit(qbs::Internal::RuleNode*) + 20 11 libqbscore.2.0.2.dylib 0x100b6a74c non-virtual thunk to qbs::Internal::Executor::visit(qbs::Internal::RuleNode*) + 16 12 libqbscore.2.0.2.dylib 0x100b9c50c qbs::Internal::RuleNode::accept(qbs::Internal::BuildGraphVisitor*) + 40 13 libqbscore.2.0.2.dylib 0x100b63c08 qbs::Internal::Executor::scheduleJobs() + 1388 14 libqbscore.2.0.2.dylib 0x100b609d8 qbs::Internal::Executor::doBuild() + 1696 15 libqbscore.2.0.2.dylib 0x100b602ec qbs::Internal::Executor::build() + 44 16 QtCore 0x1015ae760 void doActivate<false>(QObject*, int, void**) + 1204 17 QtCore 0x101633718 QThread::started(QThread::QPrivateSignal) + 56 18 QtCore 0x101699ca8 QThreadPrivate::start(void*) + 300 19 libsystem_pthread.dylib 0x19afa426c _pthread_start + 148 20 libsystem_pthread.dylib 0x19af9f08c thread_start + 8
Additional notes
- I was able to reproduce the issue on 2.1.1 as well. Also, it happened on earlier versions of Qbs (maybe 1.19 or something), but with slightly different code (I was using JavaScriptCommand with File.makePath instead of Command with mkdir -p).
- The main entry point to all the actual work is in modules/Sketch/export/export.qbs with the logic in modules/Sketch/sketch.js