aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2011-08-30 08:51:45 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2011-08-30 08:53:31 +0200
commit5bb2164f7c8b654f2312cd0a4a814b724da292f2 (patch)
treecf43b85ca7721718811bb458764e077efeffe533 /src
parentf2ad73ceb554944beb35eb8b87bab7a5a0ee9e42 (diff)
Implement backtrace debug output of leaked textures
Change-Id: I9aeece87aae393eadd32503af5eb7cd1508a732c Reviewed-on: http://codereview.qt.nokia.com/3849 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/declarative/scenegraph/util/qsgtexture.cpp104
1 files changed, 91 insertions, 13 deletions
diff --git a/src/declarative/scenegraph/util/qsgtexture.cpp b/src/declarative/scenegraph/util/qsgtexture.cpp
index d403bd6503..bec325f3bb 100644
--- a/src/declarative/scenegraph/util/qsgtexture.cpp
+++ b/src/declarative/scenegraph/util/qsgtexture.cpp
@@ -45,6 +45,12 @@
#include <qopenglfunctions.h>
#include <private/qsgcontext_p.h>
#include <qthread.h>
+#include <private/qdeclarativedebugtrace_p.h>
+
+#if !defined(QT_NO_DEBUG) && (defined(Q_OS_LINUX) || defined(Q_OS_MAC))
+#include <execinfo.h>
+#include <QHash>
+#endif
QT_BEGIN_NAMESPACE
@@ -65,36 +71,108 @@ QSGTexturePrivate::QSGTexturePrivate()
}
#ifndef QT_NO_DEBUG
-static int qt_texture_count = 0;
-static void qt_print_texture_count()
+static int qt_debug_texture_count = 0;
+
+#if defined(Q_OS_LINUX) || defined (Q_OS_MAC)
+DEFINE_BOOL_CONFIG_OPTION(qmlDebugLeakBacktrace, QML_DEBUG_LEAK_BACKTRACE)
+
+#define BACKTRACE_SIZE 20
+class SGTextureTraceItem
{
- qDebug("Number of leaked textures: %i", qt_texture_count);
- qt_texture_count = -1;
-}
+public:
+ void *backTrace[BACKTRACE_SIZE];
+ size_t backTraceSize;
+};
+
+static QHash<QSGTexture*, SGTextureTraceItem*> qt_debug_allocated_textures;
#endif
+inline static void qt_debug_print_texture_count()
+{
+ qDebug("Number of leaked textures: %i", qt_debug_texture_count);
+ qt_debug_texture_count = -1;
+#if defined(Q_OS_LINUX) || defined (Q_OS_MAC)
+ if (qmlDebugLeakBacktrace()) {
+ while (!qt_debug_allocated_textures.isEmpty()) {
+ QHash<QSGTexture*, SGTextureTraceItem*>::Iterator it = qt_debug_allocated_textures.begin();
+ QSGTexture* texture = it.key();
+ SGTextureTraceItem* item = it.value();
-QSGTexture::QSGTexture()
- : QObject(*(new QSGTexturePrivate))
+ qt_debug_allocated_textures.erase(it);
+
+ qDebug() << "------";
+ qDebug() << "Leaked" << texture << "backtrace:";
+
+ char** symbols = backtrace_symbols(item->backTrace, item->backTraceSize);
+
+ if (symbols) {
+ for (int i=0; i<(int) item->backTraceSize; i++)
+ qDebug("Backtrace <%02d>: %s", i, symbols[i]);
+ free(symbols);
+ }
+
+ qDebug() << "------";
+
+ delete item;
+ }
+ }
+#endif
+}
+
+inline static void qt_debug_add_texture(QSGTexture* texture)
{
-#ifndef QT_NO_DEBUG
- ++qt_texture_count;
+#if defined(Q_OS_LINUX) || defined (Q_OS_MAC)
+ if (qmlDebugLeakBacktrace()) {
+ SGTextureTraceItem* item = new SGTextureTraceItem;
+ item->backTraceSize = backtrace(item->backTrace, BACKTRACE_SIZE);
+ qt_debug_allocated_textures.insert(texture, item);
+ }
+#endif // Q_OS_LINUX
+
+ ++qt_debug_texture_count;
+
static bool atexit_registered = false;
if (!atexit_registered) {
- atexit(qt_print_texture_count);
+ atexit(qt_debug_print_texture_count);
atexit_registered = true;
}
+}
+
+static void qt_debug_remove_texture(QSGTexture* texture)
+{
+#if defined(Q_OS_LINUX) || defined (Q_OS_MAC)
+ if (qmlDebugLeakBacktrace()) {
+ SGTextureTraceItem* item = qt_debug_allocated_textures.value(texture, 0);
+ if (item) {
+ qt_debug_allocated_textures.remove(texture);
+ delete item;
+ }
+ }
+#endif
+
+ --qt_debug_texture_count;
+
+ if (qt_debug_texture_count < 0)
+ qDebug("Material destroyed after qt_debug_print_texture_count() was called.");
+}
+
+#endif // QT_NO_DEBUG
+
+
+QSGTexture::QSGTexture()
+ : QObject(*(new QSGTexturePrivate))
+{
+#ifndef QT_NO_DEBUG
+ qt_debug_add_texture(this);
#endif
}
QSGTexture::~QSGTexture()
{
#ifndef QT_NO_DEBUG
- --qt_texture_count;
- if (qt_texture_count < 0)
- qDebug("Material destroyed after qt_print_texture_count() was called.");
+ qt_debug_remove_texture(this);
#endif
}