From a7222838b8a3ca8a5013a237baf564787f884e79 Mon Sep 17 00:00:00 2001 From: Lieven Hey Date: Tue, 4 Jun 2024 15:13:04 +0200 Subject: [PATCH] fix: crash if hotspot is closed while loading a file The crash is caused because the destructor is called in one thread while other threads still execute. This patch waits in the destructor till all threads terminate. fixes: #654 --- src/parsers/perf/perfparser.cpp | 96 +++++++++++++-------------------- 1 file changed, 37 insertions(+), 59 deletions(-) diff --git a/src/parsers/perf/perfparser.cpp b/src/parsers/perf/perfparser.cpp index 3f61382d..4bae828c 100644 --- a/src/parsers/perf/perfparser.cpp +++ b/src/parsers/perf/perfparser.cpp @@ -56,11 +56,8 @@ QDataStream& operator>>(QDataStream& stream, Record& record) QDebug operator<<(QDebug stream, const Record& record) { - stream.noquote().nospace() << "Record{" - << "pid=" << record.pid << ", " - << "tid=" << record.tid << ", " - << "time=" << record.time << ", " - << "cpu=" << record.cpu << "}"; + stream.noquote().nospace() << "Record{" << "pid=" << record.pid << ", " << "tid=" << record.tid << ", " + << "time=" << record.time << ", " << "cpu=" << record.cpu << "}"; return stream; } @@ -76,8 +73,7 @@ QDataStream& operator>>(QDataStream& stream, StringId& stringId) QDebug operator<<(QDebug stream, StringId stringId) { - stream.noquote().nospace() << "String{" - << "id=" << stringId.id << "}"; + stream.noquote().nospace() << "String{" << "id=" << stringId.id << "}"; return stream; } @@ -109,8 +105,7 @@ QDataStream& operator>>(QDataStream& stream, AttributesDefinition& attributesDef QDebug operator<<(QDebug stream, const AttributesDefinition& attributesDefinition) { - stream.noquote().nospace() << "AttributesDefinition{" - << "id=" << attributesDefinition.id << ", " + stream.noquote().nospace() << "AttributesDefinition{" << "id=" << attributesDefinition.id << ", " << "type=" << attributesDefinition.type << ", " << "config=" << attributesDefinition.config << ", " << "name=" << attributesDefinition.name << ", " @@ -131,8 +126,8 @@ QDataStream& operator>>(QDataStream& stream, Command& command) QDebug operator<<(QDebug stream, const Command& command) { - stream.noquote().nospace() << "Command{" << static_cast(command) << ", " - << "comm=" << command.comm << "}"; + stream.noquote().nospace() << "Command{" << static_cast(command) << ", " << "comm=" << command.comm + << "}"; return stream; } @@ -189,12 +184,9 @@ QDataStream& operator>>(QDataStream& stream, Location& location) QDebug operator<<(QDebug stream, const Location& location) { - stream.noquote().nospace() << "Location{" - << "address=0x" << Qt::hex << location.address << Qt::dec << ", " - << "relAddr=" << location.relAddr << ", " - << "file=" << location.file << ", " - << "pid=" << location.pid << ", " - << "line=" << location.line << ", " + stream.noquote().nospace() << "Location{" << "address=0x" << Qt::hex << location.address << Qt::dec << ", " + << "relAddr=" << location.relAddr << ", " << "file=" << location.file << ", " + << "pid=" << location.pid << ", " << "line=" << location.line << ", " << "column=" << location.column << ", " << "parentLocationId=" << location.parentLocationId << "}"; return stream; @@ -213,8 +205,7 @@ QDataStream& operator>>(QDataStream& stream, LocationDefinition& locationDefinit QDebug operator<<(QDebug stream, const LocationDefinition& locationDefinition) { - stream.noquote().nospace() << "LocationDefinition{" - << "id=" << locationDefinition.id << ", " + stream.noquote().nospace() << "LocationDefinition{" << "id=" << locationDefinition.id << ", " << "location=" << locationDefinition.location << "}"; return stream; } @@ -239,15 +230,10 @@ QDataStream& operator>>(QDataStream& stream, Symbol& symbol) QDebug operator<<(QDebug stream, const Symbol& symbol) { - stream.noquote().nospace() << "Symbol{" - << "name=" << symbol.name << ", " - << "relAddr=" << symbol.relAddr << ", " - << "size=" << symbol.size << ", " - << "binary=" << symbol.binary << ", " - << "path=" << symbol.path << ", " - << "actualPath=" << symbol.actualPath << ", " - << "isKernel=" << symbol.isKernel << ", " - << "isInline=" << symbol.isInline << "}"; + stream.noquote().nospace() << "Symbol{" << "name=" << symbol.name << ", " << "relAddr=" << symbol.relAddr << ", " + << "size=" << symbol.size << ", " << "binary=" << symbol.binary << ", " + << "path=" << symbol.path << ", " << "actualPath=" << symbol.actualPath << ", " + << "isKernel=" << symbol.isKernel << ", " << "isInline=" << symbol.isInline << "}"; return stream; } @@ -264,8 +250,7 @@ QDataStream& operator>>(QDataStream& stream, SymbolDefinition& symbolDefinition) QDebug operator<<(QDebug stream, const SymbolDefinition& symbolDefinition) { - stream.noquote().nospace() << "SymbolDefinition{" - << "id=" << symbolDefinition.id << ", " + stream.noquote().nospace() << "SymbolDefinition{" << "id=" << symbolDefinition.id << ", " << "symbol=" << symbolDefinition.symbol << "}"; return stream; } @@ -283,8 +268,7 @@ QDataStream& operator>>(QDataStream& stream, SampleCost& sampleCost) QDebug operator<<(QDebug stream, SampleCost sampleCost) { - stream.noquote().nospace() << "SampleCost{" - << "attributeId=" << sampleCost.attributeId << ", " + stream.noquote().nospace() << "SampleCost{" << "attributeId=" << sampleCost.attributeId << ", " << "cost=" << sampleCost.cost << "}"; return stream; } @@ -303,10 +287,9 @@ QDataStream& operator>>(QDataStream& stream, Sample& sample) QDebug operator<<(QDebug stream, const Sample& sample) { - stream.noquote().nospace() << "Sample{" << static_cast(sample) << ", " - << "frames=" << sample.frames << ", " - << "guessedFrames=" << sample.guessedFrames << ", " - << "costs=" << sample.costs << "}"; + stream.noquote().nospace() << "Sample{" << static_cast(sample) << ", " << "frames=" << sample.frames + << ", " << "guessedFrames=" << sample.guessedFrames << ", " << "costs=" << sample.costs + << "}"; return stream; } @@ -340,8 +323,7 @@ QDataStream& operator>>(QDataStream& stream, StringDefinition& stringDefinition) QDebug operator<<(QDebug stream, const StringDefinition& stringDefinition) { - stream.noquote().nospace() << "StringDefinition{" - << "id=" << stringDefinition.id << ", " + stream.noquote().nospace() << "StringDefinition{" << "id=" << stringDefinition.id << ", " << "string=" << stringDefinition.string << "}"; return stream; } @@ -377,9 +359,7 @@ QDataStream& operator>>(QDataStream& stream, BuildId& buildId) QDebug operator<<(QDebug stream, const BuildId& buildId) { - stream.noquote().nospace() << "BuildId{" - << "pid=" << buildId.pid << ", " - << "id=" << buildId.id.toHex() << ", " + stream.noquote().nospace() << "BuildId{" << "pid=" << buildId.pid << ", " << "id=" << buildId.id.toHex() << ", " << "fileName=" << buildId.fileName << "}"; return stream; } @@ -399,10 +379,8 @@ QDataStream& operator>>(QDataStream& stream, NumaNode& numaNode) QDebug operator<<(QDebug stream, const NumaNode& numaNode) { - stream.noquote().nospace() << "NumaNode{" - << "nodeId=" << numaNode.nodeId << ", " - << "memTotal=" << numaNode.memTotal << ", " - << "memFree=" << numaNode.memFree << ", " + stream.noquote().nospace() << "NumaNode{" << "nodeId=" << numaNode.nodeId << ", " + << "memTotal=" << numaNode.memTotal << ", " << "memFree=" << numaNode.memFree << ", " << "topology=" << numaNode.topology << "}"; return stream; } @@ -420,9 +398,7 @@ QDataStream& operator>>(QDataStream& stream, Pmu& pmu) QDebug operator<<(QDebug stream, const Pmu& pmu) { - stream.noquote().nospace() << "Pmu{" - << "type=" << pmu.type << ", " - << "name=" << pmu.name << "}"; + stream.noquote().nospace() << "Pmu{" << "type=" << pmu.type << ", " << "name=" << pmu.name << "}"; return stream; } @@ -440,8 +416,7 @@ QDataStream& operator>>(QDataStream& stream, GroupDesc& groupDesc) QDebug operator<<(QDebug stream, const GroupDesc& groupDesc) { - stream.noquote().nospace() << "GroupDesc{" - << "name=" << groupDesc.name << ", " + stream.noquote().nospace() << "GroupDesc{" << "name=" << groupDesc.name << ", " << "leaderIndex=" << groupDesc.leaderIndex << ", " << "numMembers=" << groupDesc.numMembers << "}"; return stream; @@ -481,12 +456,10 @@ QDataStream& operator>>(QDataStream& stream, FeaturesDefinition& featuresDefinit QDebug operator<<(QDebug stream, const FeaturesDefinition& featuresDefinition) { - stream.noquote().nospace() << "FeaturesDefinition{" - << "hostName=" << featuresDefinition.hostName << ", " + stream.noquote().nospace() << "FeaturesDefinition{" << "hostName=" << featuresDefinition.hostName << ", " << "osRelease=" << featuresDefinition.osRelease << ", " - << "version=" << featuresDefinition.version << ", " - << "arch=" << featuresDefinition.arch << ", " - << "nrCpusOnline=" << featuresDefinition.nrCpusOnline << ", " + << "version=" << featuresDefinition.version << ", " << "arch=" << featuresDefinition.arch + << ", " << "nrCpusOnline=" << featuresDefinition.nrCpusOnline << ", " << "nrCpusAvailable=" << featuresDefinition.nrCpusAvailable << ", " << "cpuDesc=" << featuresDefinition.cpuDesc << ", " << "cpuId=" << featuresDefinition.cpuId << ", " @@ -528,9 +501,7 @@ QDataStream& operator>>(QDataStream& stream, Error& error) QDebug operator<<(QDebug stream, const Error& error) { - stream.noquote().nospace() << "Error{" - << "code=" << error.code << ", " - << "message=" << error.message << "}"; + stream.noquote().nospace() << "Error{" << "code=" << error.code << ", " << "message=" << error.message << "}"; return stream; } @@ -1476,7 +1447,14 @@ PerfParser::PerfParser(QObject* parent) connect(this, &PerfParser::parsingFinished, this, parsingStopped); } -PerfParser::~PerfParser() = default; +PerfParser::~PerfParser() +{ + using namespace ThreadWeaver; + auto queue = Queue::instance(); + if (!queue->isEmpty()) { + queue->shutDown(); + } +} bool PerfParser::initParserArgs(const QString& path) {