summaryrefslogtreecommitdiffstats
path: root/src/dbus/qdbus_symbols_p.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2015-01-01 17:11:32 -0200
committerThiago Macieira <thiago.macieira@intel.com>2015-01-06 19:39:45 +0100
commit1991647af1de2d0b3812d57363dddfeac6179a68 (patch)
tree6a2225c83af867bf6570a6fe26c06e5e948c0b9b /src/dbus/qdbus_symbols_p.h
parentdd8b75d8fb2503aed9e29fabf3cfd3a33a0efb5a (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.h78
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