aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <[email protected]>2023-09-28 10:54:28 +0200
committerEike Ziller <[email protected]>2023-09-28 11:20:33 +0000
commit97518b3f6a55585b9845d1395feb35c704f71f7b (patch)
treefab1dc1df53b03591387bfc43664fa9e81939d60
parent963ff4381d5a3b2edb27c1d538299e23d15d8fa1 (diff)
CtfVisualizer: Do not crash on unexpected types again
And print a nicer error message. Amends c05f9cacc6be1038a1a9ecee0af07ac84c01738c Task-number: QTCREATORBUG-29659 Change-Id: I1db6bea0bedf1fae034fecbbbeae56bb2fee49ed Reviewed-by: Jarek Kobus <[email protected]>
-rw-r--r--src/plugins/ctfvisualizer/ctftracemanager.cpp91
-rw-r--r--src/plugins/ctfvisualizer/ctftracemanager.h3
-rw-r--r--src/plugins/ctfvisualizer/ctfvisualizertool.cpp4
3 files changed, 58 insertions, 40 deletions
diff --git a/src/plugins/ctfvisualizer/ctftracemanager.cpp b/src/plugins/ctfvisualizer/ctftracemanager.cpp
index 29dbed73c28..c9fe7f2b351 100644
--- a/src/plugins/ctfvisualizer/ctftracemanager.cpp
+++ b/src/plugins/ctfvisualizer/ctftracemanager.cpp
@@ -46,50 +46,56 @@ qint64 CtfTraceManager::traceEnd() const
void CtfTraceManager::addEvent(const json &event)
{
- const double timestamp = event.value(CtfTracingClockTimestampKey, -1.0);
- if (timestamp < 0) {
- // events without or with negative timestamp will be ignored
- return;
- }
- if (m_timeOffset < 0) {
- // the timestamp of the first event is used as the global offset
- m_timeOffset = timestamp;
- }
+ try {
+ const double timestamp = event.value(CtfTracingClockTimestampKey, -1.0);
+ if (timestamp < 0) {
+ // events without or with negative timestamp will be ignored
+ return;
+ }
+ if (m_timeOffset < 0) {
+ // the timestamp of the first event is used as the global offset
+ m_timeOffset = timestamp;
+ }
- static const auto getStringValue = [](const json &event, const char *key, const QString &def) {
- if (!event.contains(key))
- return def;
- const json val = event[key];
- if (val.is_string())
- return QString::fromStdString(val);
- if (val.is_number()) {
- return QString::number(int(val));
+ static const auto getStringValue =
+ [](const json &event, const char *key, const QString &def) {
+ if (!event.contains(key))
+ return def;
+ const json val = event[key];
+ if (val.is_string())
+ return QString::fromStdString(val);
+ if (val.is_number()) {
+ return QString::number(int(val));
+ }
+ return def;
+ };
+ const QString processId = getStringValue(event, CtfProcessIdKey, "0");
+ const QString threadId = getStringValue(event, CtfThreadIdKey, processId);
+ if (!m_threadModels.contains(threadId)) {
+ addModelForThread(threadId, processId);
}
- return def;
- };
- const QString processId = getStringValue(event, CtfProcessIdKey, "0");
- const QString threadId = getStringValue(event, CtfThreadIdKey, processId);
- if (!m_threadModels.contains(threadId)) {
- addModelForThread(threadId, processId);
- }
- if (event.value(CtfEventPhaseKey, "") == CtfEventTypeMetadata) {
- const std::string name = event[CtfEventNameKey];
- if (name == "thread_name") {
- m_threadNames[threadId] = QString::fromStdString(event["args"]["name"]);
- } else if (name == "process_name") {
- m_processNames[processId] = QString::fromStdString(event["args"]["name"]);
+ if (event.value(CtfEventPhaseKey, "") == CtfEventTypeMetadata) {
+ const std::string name = event[CtfEventNameKey];
+ if (name == "thread_name") {
+ m_threadNames[threadId] = QString::fromStdString(event["args"]["name"]);
+ } else if (name == "process_name") {
+ m_processNames[processId] = QString::fromStdString(event["args"]["name"]);
+ }
}
- }
- const QPair<bool, qint64> result = m_threadModels[threadId]->addEvent(event, m_timeOffset);
- const bool visibleOnTimeline = result.first;
- if (visibleOnTimeline) {
- m_traceBegin = std::min(m_traceBegin, timestamp);
- m_traceEnd = std::max(m_traceEnd, timestamp);
- } else if (m_timeOffset == timestamp) {
- // this timestamp was used as the time offset but it is not a visible element
- // -> reset the time offset again:
- m_timeOffset = -1.0;
+ const QPair<bool, qint64> result = m_threadModels[threadId]->addEvent(event, m_timeOffset);
+ const bool visibleOnTimeline = result.first;
+ if (visibleOnTimeline) {
+ m_traceBegin = std::min(m_traceBegin, timestamp);
+ m_traceEnd = std::max(m_traceEnd, timestamp);
+ } else if (m_timeOffset == timestamp) {
+ // this timestamp was used as the time offset but it is not a visible element
+ // -> reset the time offset again:
+ m_timeOffset = -1.0;
+ }
+ } catch (...) {
+ m_errorString = Tr::tr("Error while parsing CTF data: %1.")
+ .arg("<pre>" + QString::fromStdString(event.dump()) + "</pre>");
}
}
@@ -216,6 +222,7 @@ void CtfTraceManager::updateStatistics()
void CtfTraceManager::clearAll()
{
+ m_errorString.clear();
m_modelAggregator->clear();
for (CtfTimelineModel *model: std::as_const(m_threadModels)) {
model->deleteLater();
@@ -226,6 +233,10 @@ void CtfTraceManager::clearAll()
m_timeOffset = -1;
}
+QString CtfTraceManager::errorString() const
+{
+ return m_errorString;
+}
} // namespace Internal
} // namespace CtfVisualizer
diff --git a/src/plugins/ctfvisualizer/ctftracemanager.h b/src/plugins/ctfvisualizer/ctftracemanager.h
index 29694740297..82d879ab463 100644
--- a/src/plugins/ctfvisualizer/ctftracemanager.h
+++ b/src/plugins/ctfvisualizer/ctftracemanager.h
@@ -46,6 +46,8 @@ public:
void updateStatistics();
void clearAll();
+ QString errorString() const;
+
signals:
void detailsRequested(const QString &title);
@@ -66,6 +68,7 @@ protected:
double m_traceEnd = std::numeric_limits<double>::min();
double m_timeOffset = -1.0;
+ QString m_errorString;
};
} // namespace Internal
diff --git a/src/plugins/ctfvisualizer/ctfvisualizertool.cpp b/src/plugins/ctfvisualizer/ctfvisualizertool.cpp
index 6aee14e1236..7e21050d9d8 100644
--- a/src/plugins/ctfvisualizer/ctfvisualizertool.cpp
+++ b/src/plugins/ctfvisualizer/ctfvisualizertool.cpp
@@ -231,6 +231,10 @@ void CtfVisualizerTool::loadJson(const QString &fileName)
QMessageBox::warning(Core::ICore::dialogParent(),
Tr::tr("CTF Visualizer"),
Tr::tr("The file does not contain any trace data."));
+ } else if (!m_traceManager->errorString().isEmpty()) {
+ QMessageBox::warning(Core::ICore::dialogParent(),
+ Tr::tr("CTF Visualizer"),
+ m_traceManager->errorString());
} else {
m_traceManager->finalize();
m_perspective.select();