From 56633822be9fa3d646eb56bd5c3526ff0c46d3ee Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Wed, 8 Apr 2026 22:46:51 -0700 Subject: [PATCH] add debug ld hook --- src/core/CMakeLists.txt | 1 + src/core/hook.cpp | 86 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/core/hook.cpp diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4824965..67ea3f5 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -43,6 +43,7 @@ qt_add_library(quickshell-core STATIC toolsupport.cpp streamreader.cpp debuginfo.cpp + hook.cpp ) qt_add_qml_module(quickshell-core diff --git a/src/core/hook.cpp b/src/core/hook.cpp new file mode 100644 index 0000000..68c73e9 --- /dev/null +++ b/src/core/hook.cpp @@ -0,0 +1,86 @@ +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +__attribute__((constructor)) static void initHook() { + unsetenv("LD_PRELOAD"); +} + +Q_LOGGING_CATEGORY(logDestructors, "quickshell.destructors"); +Q_LOGGING_CATEGORY(logPostEvent, "quickshell.postEvent"); + +static std::string traceAddrs() { + std::array frames{}; + auto count = cpptrace::safe_generate_raw_trace(frames.data(), frames.size(), 1); + std::string result; + for (size_t i = 0; i < count; i++) { + if (i > 0) result += ','; + char buf[20]; + snprintf(buf, sizeof(buf), "%p", reinterpret_cast(frames[i])); + result += buf; + } + return result; +} + +using VoidMemberFn = void (*)(QObject*); + +static VoidMemberFn realD2() { + static auto fn = reinterpret_cast(dlsym(RTLD_NEXT, "_ZN7QObjectD2Ev")); + return fn; +} + +static VoidMemberFn realDeleteLater() { + static auto fn = + reinterpret_cast(dlsym(RTLD_NEXT, "_ZN7QObject11deleteLaterEv")); + return fn; +} + +using PostEventFn = void (*)(QObject*, QEvent*, int); + +static PostEventFn realPostEvent() { + static auto fn = reinterpret_cast( + dlsym(RTLD_NEXT, "_ZN16QCoreApplication9postEventEP7QObjectP6QEventi") + ); + return fn; +} + +extern "C" { + +void _ZN7QObjectD2Ev(QObject* self) { + const auto* meta = self->metaObject(); + auto trace = traceAddrs(); + qCDebug(logDestructors, "~QObject %p %s\n%s", static_cast(self), meta->className(), trace.c_str()); + realD2()(self); +} + +void _ZN7QObject11deleteLaterEv(QObject* self) { + const auto* meta = self->metaObject(); + auto trace = traceAddrs(); + qCDebug(logDestructors, "deleteLater %p %s\n%s", static_cast(self), meta->className(), trace.c_str()); + realDeleteLater()(self); +} + +void _ZN16QCoreApplication9postEventEP7QObjectP6QEventi( + QObject* receiver, + QEvent* event, + int priority +) { + //if (event->type() == QEvent::User + 1) { + const auto* meta = receiver->metaObject(); + auto trace = traceAddrs(); + qCDebug(logPostEvent, "%p %d %s\n%s", static_cast(receiver), event->type(), meta->className(), trace.c_str()); + //} + realPostEvent()(receiver, event, priority); +} + +} // extern "C"