This is the last post on the instrumenting source code series. I hope you to find the tricks below as useful as the previous ones.
In this post I show some more useful debugging tricks. Don’t forget to have a look at the other posts of the series:
- GStreamer WebKit debugging tricks using GDB (1/2)
- GStreamer WebKit debugging tricks using GDB (2/2)
- GStreamer WebKit debugging by instrumenting source code (1/3)
- GStreamer WebKit debugging by instrumenting source code (2/3)
Finding memory leaks in a RefCounted subclass
The source code shown below must be placed in the .h where the class to be debugged is defined. It’s written in a way that doesn’t need to rebuild RefCounted.h
, so it saves a lot of build time. It logs all refs, unrefs and adoptPtrs, so that any anomaly in the refcounting can be traced and investigated later. To use it, just make your class inherit from LoggedRefCounted
instead of RefCounted
.
Example output:
void WTF::adopted(WTF::LoggedRefCounted<T>*) [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1 void WTF::adopted(WTF::LoggedRefCounted<T>*) [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1 ^^^ Two adopts, this is not good. void WTF::LoggedRefCounted<T>::ref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1 --> ... void WTF::LoggedRefCounted<T>::ref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount ... --> 2 void WTF::LoggedRefCounted<T>::deref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 2 --> ... void WTF::LoggedRefCounted<T>::deref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount ... --> 1 void WTF::adopted(WTF::LoggedRefCounted<T>*) [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1 void WTF::LoggedRefCounted<T>::deref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1 --> ... void WTF::LoggedRefCounted<T>::deref() [with T = WebCore::MediaSourceClientGStreamerMSE]: this=0x673c07a4, refCount 1 --> ... ^^^ Two recursive derefs, not good either.
#include "Logging.h" namespace WTF { template<typename T> class LoggedRefCounted : public WTF::RefCounted<T> { WTF_MAKE_NONCOPYABLE(LoggedRefCounted); WTF_MAKE_FAST_ALLOCATED; public: void ref() { printf("%s: this=%p, refCount %d --> ...\n", __PRETTY_FUNCTION__, this, WTF::RefCounted<T>::refCount()); fflush(stdout); WTF::RefCounted<T>::ref(); printf("%s: this=%p, refCount ... --> %d\n", __PRETTY_FUNCTION__, this, WTF::RefCounted<T>::refCount()); fflush(stdout); } void deref() { printf("%s: this=%p, refCount %d --> ...\n", __PRETTY_FUNCTION__, this, WTF::RefCounted<T>::refCount()); fflush(stdout); WTF::RefCounted<T>::deref(); printf("%s: this=%p, refCount ... --> %d\n", __PRETTY_FUNCTION__, this, WTF::RefCounted<T>::refCount()); fflush(stdout); } protected: LoggedRefCounted() { } ~LoggedRefCounted() { } }; template<typename T> inline void adopted(WTF::LoggedRefCounted<T>* object) { printf("%s: this=%p, refCount %d\n", __PRETTY_FUNCTION__, object, (object)?object->refCount():0); fflush(stdout); adopted(static_cast<RefCountedBase*>(object)); } } // Namespace WTF
Pause WebProcess on launch
WebProcessMainGtk and WebProcessMainWPE will sleep for 30 seconds if a special environment variable is defined:
export WEBKIT2_PAUSE_WEB_PROCESS_ON_LAUNCH=1
It only works #if ENABLE(DEVELOPER_MODE)
, so you might want to remove those ifdefs if you’re building in Release mode.
Log tracers
In big pipelines (e.g. playbin) it can be very hard to find what element is replying to a query or handling an event. Even using gdb can be extremely tedious due to the very high level of recursion. My coworker Alicia commented that using log tracers is more helpful in this case.
GST_TRACERS=log
enables additional GST_TRACE() calls all accross GStreamer. The following example logs entries and exits into the query function.
GST_TRACERS=log GST_DEBUG='query:TRACE'
The names of the logging categories are somewhat inconsistent:
- log (the log tracer itself)
- GST_BUFFER
- GST_BUFFER_LIST
- GST_EVENT
- GST_MESSAGE
- GST_STATES
- GST_PADS
- GST_ELEMENT_PADS
- GST_ELEMENT_FACTORY
- query
- bin
The log tracer code is in subprojects/gstreamer/plugins/tracers/gstlog.c
.