From 1991647af1de2d0b3812d57363dddfeac6179a68 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 1 Jan 2015 17:11:32 -0200 Subject: Add a simple way of tracing calls to libdbus-1 Very useful to track memory leaks and other silly stuff going wrong. Requires C++11, but since it isn't enabled by default, it's not a problem. ALso, only works with "runtime" dbus -- for linked, use ltrace(1) instead. Change-Id: Iccb18516cfb729b2b1bf9ee592df4a1adefeb3b7 Reviewed-by: Alex Blasche --- src/dbus/qdbus_symbols_p.h | 78 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) (limited to 'src/dbus/qdbus_symbols_p.h') diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h index 88c51947ed..6175e3ccde 100644 --- a/src/dbus/qdbus_symbols_p.h +++ b/src/dbus/qdbus_symbols_p.h @@ -64,14 +64,90 @@ void (*qdbus_resolve_conditionally(const char *name))(); // doesn't print a warn void (*qdbus_resolve_me(const char *name))(); // prints a warning bool qdbus_loadLibDBus(); +//# define TRACE_DBUS_CALLS +# ifdef TRACE_DBUS_CALLS +namespace QtDBusCallTracing { +struct TraceDBusCall +{ + struct ThreadData { + TraceDBusCall *ptr; + int level; + bool finishedPrinted; + }; + + static inline ThreadData &td() + { + static thread_local ThreadData value; + return value; + } + + ThreadData savedData; + QDebug s; + TraceDBusCall(QDebug s, const char *fname) + : savedData(td()), s(s.nospace() << QByteArray(savedData.level * 3, ' ').constData() << fname) + { + if (savedData.ptr && !savedData.finishedPrinted) { + savedData.ptr->s << " ...unfinished"; + savedData.ptr->s = qDebug().nospace() << QByteArray(savedData.level * 3 - 3, ' ').constData(); + savedData.finishedPrinted = true; + } + ThreadData &data = td(); + data.ptr = this; + data.level++; + data.finishedPrinted = false; + } + ~TraceDBusCall() + { + td() = savedData; + } + + void operator()() { s << ")"; } + template void operator()(const char *arg1, Args &&... args) + { + s << '"' << arg1 << '"'; + if (sizeof...(args)) + s << ", "; + operator()(args...); + } + template void operator()(Arg1 &&arg1, Args &&... args) + { + s << arg1; + if (sizeof...(args)) + s << ", "; + operator()(args...); + } +}; +template T operator,(TraceDBusCall &&tc, T &&ret) +{ + tc.s << " = " << ret; + return ret; +} +inline const char *operator,(TraceDBusCall &&tc, const char *ret) +{ + tc.s << " = \"" << ret << '"'; + return ret; +} + +template struct TraceReturn { typedef TraceDBusCall Type; }; +template <> struct TraceReturn { typedef void Type; }; +} + +# define DEBUGCALL(name, argcall) QtDBusCallTracing::TraceDBusCall tc(qDebug(), name "("); tc argcall +# define DEBUGRET(ret) (QtDBusCallTracing::TraceReturn::Type) tc , +# else +# define DEBUGCALL(name, argcall) +# define DEBUGRET(ret) +# endif + # define DEFINEFUNC(ret, func, args, argcall, funcret) \ typedef ret (* _q_PTR_##func) args; \ static inline ret q_##func args \ { \ static _q_PTR_##func ptr; \ + DEBUGCALL(#func, argcall); \ if (!ptr) \ ptr = (_q_PTR_##func) qdbus_resolve_me(#func); \ - funcret ptr argcall; \ + funcret DEBUGRET(ret) ptr argcall; \ } #else // defined QT_LINKED_LIBDBUS -- cgit v1.2.3