Index: trac/web/main.py
===================================================================
--- trac/web/main.py	(revision 6489)
+++ trac/web/main.py	(working copy)
@@ -390,6 +390,17 @@
     finally:
         if env and not run_once:
             env.shutdown(threading._get_ident())
+            # Now it's a good time to do some clean-ups
+            import gc
+            gc.disable()
+            gc.set_debug(gc.DEBUG_UNCOLLECTABLE)
+            unreachable = gc.collect()
+            env.log.info("%d unreachable objects found.", unreachable)
+            uncollectable = len(gc.garbage)
+            if uncollectable:
+                del gc.garbage[:]
+                env.log.warn("%d uncollectable objects found.", uncollectable)
+            print_gc_stats(env)
 
 def _dispatch_request(req, env, env_error):
     resp = []
@@ -428,6 +439,8 @@
         if env:
             env.log.exception(e)
 
+        raise e # DEBUG - short-circuit Trac error reporting
+
         exc_info = sys.exc_info()
         try:
             message = "%s: %s" % (e.__class__.__name__, to_unicode(e))
@@ -557,3 +570,51 @@
         else:
             envs[env_name] = env_path
     return envs
+
+
+def print_gc_stats(env):
+    print '---------------- GC stats ----------------------'
+    import gc
+    live_objects = {}
+    for obj in gc.get_objects():
+        live_objects[id(obj)] = type(obj)
+    print "live objects: ", len(live_objects)
+    first = True
+    if hasattr(env, '_accumulated'):
+        first = False
+        accumulated = env._accumulated
+        stats = env._stats
+        print "accumulated objects: ", len(accumulated)
+    else:
+        accumulated = env._accumulated = {}
+        stats = env._stats = {}
+    # retrieving previous stats
+    oldstats = {}
+    for t,cnt in stats.iteritems():
+        oldstats[t] = [cnt[0]]
+    # analysing new stuff
+    for i,t in live_objects.iteritems():
+        if i not in accumulated:
+            cnt = stats.setdefault(t, [0])
+            cnt[0] += 1
+            accumulated[i] = t
+    if first:
+        return []
+    # removing old stuff
+    delete = []
+    for i,t in accumulated.iteritems():
+        if i not in live_objects:
+            cnt = stats[t]
+            cnt[0] -= 1
+            delete.append(i)
+    for i in delete:
+        del accumulated[i]
+    print 'stats by type:'
+    for t in sorted(stats.keys(), key=lambda x: str(x)):
+        newval = stats[t]
+        oldval = oldstats.get(t)
+        if not oldval:
+            print t, 'delta:', newval
+        elif oldval[0] != newval[0]:
+            print t, 'total:', newval[0], 'delta:', newval[0] - oldval[0]
+    print '------------------------------------------------'

