forked from qt-creator/qt-creator
QmlProfiler: Fix crash at startup if file creation fails
If opening the temporary file for QmlProfilerEventStorage fails in it's destructor, it was crashing, because the error handler tried to emit a signal on an object that wasn't even half constructed yet. Can be tested by forcing the return value of TraceStashFile::open to `false`. Delay the construction of the event storage a bit and do not set the error handler in its constructor, since nobody could connect to the signal that was sent yet anyway. Also add some checks before calling the error handler. Change-Id: I0fc1207aac447090e12f6b2342e156312e0d1d1b Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -130,7 +130,8 @@ public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
file.remove();
|
||||
if (!file.fileName().isEmpty())
|
||||
file.remove();
|
||||
stream.setDevice(nullptr);
|
||||
}
|
||||
|
||||
|
@@ -88,12 +88,9 @@ public:
|
||||
int resolveStackTop();
|
||||
};
|
||||
|
||||
QmlProfilerModelManager::QmlProfilerModelManager(QObject *parent) :
|
||||
Timeline::TimelineTraceManager(
|
||||
std::make_unique<QmlProfilerEventStorage>(
|
||||
std::bind(&Timeline::TimelineTraceManager::error, this, std::placeholders::_1)),
|
||||
std::make_unique<QmlProfilerEventTypeStorage>(), parent),
|
||||
d(new QmlProfilerModelManagerPrivate)
|
||||
QmlProfilerModelManager::QmlProfilerModelManager(QObject *parent)
|
||||
: Timeline::TimelineTraceManager({}, std::make_unique<QmlProfilerEventTypeStorage>(), parent)
|
||||
, d(new QmlProfilerModelManagerPrivate)
|
||||
{
|
||||
setNotesModel(new QmlProfilerNotesModel(this));
|
||||
d->textMarkModel = new Internal::QmlProfilerTextMarkModel(this);
|
||||
@@ -103,6 +100,10 @@ QmlProfilerModelManager::QmlProfilerModelManager(QObject *parent) :
|
||||
this, &QmlProfilerModelManager::setTypeDetails);
|
||||
connect(d->detailsRewriter, &Internal::QmlProfilerDetailsRewriter::eventDetailsChanged,
|
||||
this, &QmlProfilerModelManager::typeDetailsFinished);
|
||||
auto storage = new QmlProfilerEventStorage(QmlProfilerEventStorage::ErrorHandler());
|
||||
storage->setErrorHandler([this](const QString &message) { emit error(message); });
|
||||
std::unique_ptr<Timeline::TraceEventStorage> storagePtr(storage);
|
||||
swapEventStorage(storagePtr);
|
||||
}
|
||||
|
||||
QmlProfilerModelManager::~QmlProfilerModelManager()
|
||||
@@ -486,7 +487,7 @@ QmlProfilerEventStorage::QmlProfilerEventStorage(
|
||||
const std::function<void (const QString &)> &errorHandler)
|
||||
: m_file("qmlprofiler-data"), m_errorHandler(errorHandler)
|
||||
{
|
||||
if (!m_file.open())
|
||||
if (!m_file.open() && m_errorHandler)
|
||||
errorHandler(Tr::tr("Cannot open temporary trace file to store events."));
|
||||
}
|
||||
|
||||
@@ -506,13 +507,13 @@ void QmlProfilerEventStorage::clear()
|
||||
{
|
||||
m_size = 0;
|
||||
m_file.clear();
|
||||
if (!m_file.open())
|
||||
if (!m_file.open() && m_errorHandler)
|
||||
m_errorHandler(Tr::tr("Failed to reset temporary trace file."));
|
||||
}
|
||||
|
||||
void QmlProfilerEventStorage::finalize()
|
||||
{
|
||||
if (!m_file.flush())
|
||||
if (!m_file.flush() && m_errorHandler)
|
||||
m_errorHandler(Tr::tr("Failed to flush temporary trace file."));
|
||||
}
|
||||
|
||||
@@ -534,13 +535,15 @@ bool QmlProfilerEventStorage::replay(
|
||||
case Timeline::TraceStashFile<QmlEvent>::ReplaySuccess:
|
||||
return true;
|
||||
case Timeline::TraceStashFile<QmlEvent>::ReplayOpenFailed:
|
||||
m_errorHandler(Tr::tr("Could not re-open temporary trace file."));
|
||||
if (m_errorHandler)
|
||||
m_errorHandler(Tr::tr("Could not re-open temporary trace file."));
|
||||
break;
|
||||
case Timeline::TraceStashFile<QmlEvent>::ReplayLoadFailed:
|
||||
// Happens if the loader rejects an event. Not an actual error
|
||||
break;
|
||||
case Timeline::TraceStashFile<QmlEvent>::ReplayReadPastEnd:
|
||||
m_errorHandler(Tr::tr("Read past end in temporary trace file."));
|
||||
if (m_errorHandler)
|
||||
m_errorHandler(Tr::tr("Read past end in temporary trace file."));
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
Reference in New Issue
Block a user