diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2015-01-01 17:11:32 -0200 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-01-06 19:39:45 +0100 |
commit | 1991647af1de2d0b3812d57363dddfeac6179a68 (patch) | |
tree | 6a2225c83af867bf6570a6fe26c06e5e948c0b9b /src/dbus/qdbus_symbols_p.h | |
parent | dd8b75d8fb2503aed9e29fabf3cfd3a33a0efb5a (diff) |
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 <alexander.blasche@theqtcompany.com>
Diffstat (limited to 'src/dbus/qdbus_symbols_p.h')
-rw-r--r-- | src/dbus/qdbus_symbols_p.h | 78 |
1 files changed, 77 insertions, 1 deletions
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 <typename... Args> void operator()(const char *arg1, Args &&... args) + { + s << '"' << arg1 << '"'; + if (sizeof...(args)) + s << ", "; + operator()(args...); + } + template <typename Arg1, typename... Args> void operator()(Arg1 &&arg1, Args &&... args) + { + s << arg1; + if (sizeof...(args)) + s << ", "; + operator()(args...); + } +}; +template <typename T> 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 <typename T> struct TraceReturn { typedef TraceDBusCall Type; }; +template <> struct TraceReturn<void> { typedef void Type; }; +} + +# define DEBUGCALL(name, argcall) QtDBusCallTracing::TraceDBusCall tc(qDebug(), name "("); tc argcall +# define DEBUGRET(ret) (QtDBusCallTracing::TraceReturn<ret>::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 |