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>bb10
parent
dd8b75d8fb
commit
1991647af1
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue