From dbcaa6d01ed6fd510f8b36bbe69fc1c9d8e21d88 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 9 May 2018 20:52:29 +0200 Subject: [PATCH] Tracepoints: add tracing for QEvents Add tracepoints in all the main codepaths for event handling: * QEvent ctors/dtor * QCoreApplication::postEvent, sendEvent and sendSpontaneousEvent * QCoreApplication / QApplication::notify, and around the handling of event filters as well I'm switching the name of the tracepoints themselves to have the very same casing of the functions in Qt's own source code, this improves readability a lot. The pre-existing ones will be changed in an upcoming patch. Change-Id: Iae2ba2bfdd76a82c85445bb5b86434e910427a70 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira Reviewed-by: Rafael Roquetto --- src/corelib/kernel/qcoreapplication.cpp | 29 ++++++++++++++++++++++--- src/corelib/kernel/qcoreevent.cpp | 8 ++++++- src/corelib/qtcore.tracepoints | 15 +++++++++++++ src/widgets/kernel/qapplication.cpp | 23 +++++++++++++++++--- src/widgets/qtwidgets.tracepoints | 4 ++++ src/widgets/widgets.pro | 3 +++ 6 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 src/widgets/qtwidgets.tracepoints diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index bbbfe43c5e..663b917310 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1185,16 +1185,31 @@ bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, Q */ bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event) { + // Note: when adjusting the tracepoints in here + // consider adjusting QApplicationPrivate::notify_helper too. + Q_TRACE(QCoreApplication_notify_entry, receiver, event, event->type()); + // send to all application event filters (only does anything in the main thread) if (QCoreApplication::self && receiver->d_func()->threadData->thread == mainThread() - && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) + && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) { + Q_TRACE(QCoreApplication_notify_event_filtered, receiver, event, event->type()); return true; + } // send to all receiver event filters - if (sendThroughObjectEventFilters(receiver, event)) + if (sendThroughObjectEventFilters(receiver, event)) { + Q_TRACE(QCoreApplication_notify_event_filtered, receiver, event, event->type()); return true; + } + + Q_TRACE(QCoreApplication_notify_before_delivery, receiver, event, event->type()); + // deliver the event - return receiver->event(event); + const bool consumed = receiver->event(event); + + Q_TRACE(QCoreApplication_notify_after_delivery, receiver, event, event->type(), consumed); + + return consumed; } /*! @@ -1416,6 +1431,8 @@ void QCoreApplication::exit(int returnCode) */ bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event) { + Q_TRACE(QCoreApplication_sendEvent, receiver, event, event->type()); + if (event) event->spont = false; return notifyInternal2(receiver, event); @@ -1426,6 +1443,8 @@ bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event) */ bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event) { + Q_TRACE(QCoreApplication_sendSpontaneousEvent, receiver, event, event->type()); + if (event) event->spont = true; return notifyInternal2(receiver, event); @@ -1460,6 +1479,8 @@ bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event) */ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) { + Q_TRACE(QCoreApplication_postEvent_entry, receiver, event, event->type()); + if (receiver == 0) { qWarning("QCoreApplication::postEvent: Unexpected null receiver"); delete event; @@ -1496,6 +1517,7 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) // if this is one of the compressible events, do compression if (receiver->d_func()->postedEvents && self && self->compressEvent(event, receiver, &data->postEventList)) { + Q_TRACE(QCoreApplication_postEvent_event_compressed, receiver, event); return; } @@ -1527,6 +1549,7 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) // delete the event on exceptions to protect against memory leaks till the event is // properly owned in the postEventList QScopedPointer eventDeleter(event); + Q_TRACE(QCoreApplication_postEvent_event_posted, receiver, event, event->type()); data->postEventList.addEvent(QPostEvent(receiver, event, priority)); eventDeleter.take(); event->posted = true; diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 58ca8279ea..e34fe3f955 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -44,6 +44,8 @@ #include "qbasicatomic.h" +#include + #include QT_BEGIN_NAMESPACE @@ -288,7 +290,9 @@ QT_BEGIN_NAMESPACE */ QEvent::QEvent(Type type) : d(0), t(type), posted(false), spont(false), m_accept(true) -{} +{ + Q_TRACE(QEvent_ctor, this, t); +} /*! \internal @@ -301,6 +305,7 @@ QEvent::QEvent(const QEvent &other) : d(other.d), t(other.t), posted(other.posted), spont(other.spont), m_accept(other.m_accept) { + Q_TRACE(QEvent_ctor, this, t); // if QEventPrivate becomes available, make sure to implement a // virtual QEventPrivate *clone() const; function so we can copy here Q_ASSERT_X(!d, "QEvent", "Impossible, this can't happen: QEventPrivate isn't defined anywhere"); @@ -333,6 +338,7 @@ QEvent &QEvent::operator=(const QEvent &other) QEvent::~QEvent() { + Q_TRACE(QEvent_dtor, this, t); if (posted && QCoreApplication::instance()) QCoreApplicationPrivate::removePostedEvent(this); Q_ASSERT_X(!d, "QEvent", "Impossible, this can't happen: QEventPrivate isn't defined anywhere"); diff --git a/src/corelib/qtcore.tracepoints b/src/corelib/qtcore.tracepoints index e6b666ac74..06b7d70f9c 100644 --- a/src/corelib/qtcore.tracepoints +++ b/src/corelib/qtcore.tracepoints @@ -3,3 +3,18 @@ qcoreapplicationprivate_init_exit() qfactoryloader_update(const QString &fileName) qlibraryprivate_load_entry(const QString &fileName) qlibraryprivate_load_exit(bool success) + +QEvent_ctor(QEvent *event, int type) +QEvent_dtor(QEvent *event, int type) + +QCoreApplication_postEvent_entry(QObject *receiver, QEvent *event, int type) +QCoreApplication_postEvent_event_compressed(QObject *receiver, QEvent *event) +QCoreApplication_postEvent_event_posted(QObject *receiver, QEvent *event, int type) + +QCoreApplication_sendEvent(QObject *receiver, QEvent *event, int type) +QCoreApplication_sendSpontaneousEvent(QObject *receiver, QEvent *event, int type) + +QCoreApplication_notify_entry(QObject *receiver, QEvent *event, int type) +QCoreApplication_notify_event_filtered(QObject *receiver, QEvent *event, int type) +QCoreApplication_notify_before_delivery(QObject *receiver, QEvent *event, int type) +QCoreApplication_notify_after_delivery(QObject *receiver, QEvent *event, int type, bool consumed) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 5dae8a7a0d..581b7c9c94 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -110,6 +110,8 @@ #include +#include + //#define ALIEN_DEBUG static void initResources() @@ -3707,11 +3709,19 @@ bool QApplication::notify(QObject *receiver, QEvent *e) bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e) { + // These tracepoints (and the whole function, actually) are very similar + // to the ones in QCoreApplicationPrivate::notify_helper; the reason for their + // duplication is because tracepoint symbols are not exported by QtCore. + // If you adjust the tracepoints here, consider adjusting QCoreApplicationPrivate too. + Q_TRACE(QApplication_notify_entry, receiver, e, e->type()); + // send to all application event filters if (threadRequiresCoreApplication() && receiver->d_func()->threadData->thread == mainThread() - && sendThroughApplicationEventFilters(receiver, e)) + && sendThroughApplicationEventFilters(receiver, e)) { + Q_TRACE(QApplication_notify_event_filtered, receiver, e, e->type()); return true; + } if (receiver->isWidgetType()) { QWidget *widget = static_cast(receiver); @@ -3731,11 +3741,18 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e) } // send to all receiver event filters - if (sendThroughObjectEventFilters(receiver, e)) + if (sendThroughObjectEventFilters(receiver, e)) { + Q_TRACE(QApplication_notify_event_filtered, receiver, e, e->type()); return true; + } + + Q_TRACE(QApplication_notify_before_delivery, receiver, e, e->type()); // deliver the event - bool consumed = receiver->event(e); + const bool consumed = receiver->event(e); + + Q_TRACE(QApplication_notify_after_delivery, receiver, e, e->type(), consumed); + QCoreApplicationPrivate::setEventSpontaneous(e, false); return consumed; } diff --git a/src/widgets/qtwidgets.tracepoints b/src/widgets/qtwidgets.tracepoints new file mode 100644 index 0000000000..01a1383670 --- /dev/null +++ b/src/widgets/qtwidgets.tracepoints @@ -0,0 +1,4 @@ +QApplication_notify_entry(QObject *receiver, QEvent *event, int type) +QApplication_notify_event_filtered(QObject *receiver, QEvent *event, int type) +QApplication_notify_before_delivery(QObject *receiver, QEvent *event, int type) +QApplication_notify_after_delivery(QObject *receiver, QEvent *event, int type, bool consumed) diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro index e028a691c8..e556cb8b10 100644 --- a/src/widgets/widgets.pro +++ b/src/widgets/widgets.pro @@ -6,6 +6,9 @@ CONFIG += $$MODULE_CONFIG DEFINES += QT_NO_USING_NAMESPACE msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x65000000 +TRACEPOINT_PROVIDER = $$PWD/qtwidgets.tracepoints +CONFIG += qt_tracepoints + QMAKE_DOCS = $$PWD/doc/qtwidgets.qdocconf #platforms