]> granicus.if.org Git - postgresql/commitdiff
Improve error reporting in code that checks for buffer refcount leaks.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 15 Mar 2013 16:26:26 +0000 (12:26 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 15 Mar 2013 16:26:26 +0000 (12:26 -0400)
Formerly we just Assert'ed that each refcount was zero, which was quick
and easy but failed to provide a good overview of what was wrong.
Change the code so that we'll call PrintBufferLeakWarning() for each
buffer with a nonzero refcount, and then Assert at the end of the loop.
This costs nothing in runtime and might ease diagnosis of some bugs.

Greg Smith, reviewed by Satoshi Nagayasu, further tweaked by me

src/backend/storage/buffer/bufmgr.c
src/backend/storage/buffer/localbuf.c

index ea7d469f2f412212fc531ece5ef58f3732467da0..0b4c2ed0a018c62d8bc8b9b7134f5cecbce0e356 100644 (file)
@@ -1699,12 +1699,18 @@ AtEOXact_Buffers(bool isCommit)
 #ifdef USE_ASSERT_CHECKING
        if (assert_enabled)
        {
-               int                     i;
+               int                     RefCountErrors = 0;
+               Buffer          b;
 
-               for (i = 0; i < NBuffers; i++)
+               for (b = 1; b <= NBuffers; b++)
                {
-                       Assert(PrivateRefCount[i] == 0);
+                       if (PrivateRefCount[b - 1] != 0)
+                       {
+                               PrintBufferLeakWarning(b);
+                               RefCountErrors++;
+                       }
                }
+               Assert(RefCountErrors == 0);
        }
 #endif
 
@@ -1739,12 +1745,18 @@ AtProcExit_Buffers(int code, Datum arg)
 #ifdef USE_ASSERT_CHECKING
        if (assert_enabled)
        {
-               int                     i;
+               int                     RefCountErrors = 0;
+               Buffer          b;
 
-               for (i = 0; i < NBuffers; i++)
+               for (b = 1; b <= NBuffers; b++)
                {
-                       Assert(PrivateRefCount[i] == 0);
+                       if (PrivateRefCount[b - 1] != 0)
+                       {
+                               PrintBufferLeakWarning(b);
+                               RefCountErrors++;
+                       }
                }
+               Assert(RefCountErrors == 0);
        }
 #endif
 
index 30dc8098ed2f92c7fa9c36d210df992a81aa54a9..03055c96d8538c70654b521db9b1ed12f8b1e8df 100644 (file)
@@ -497,14 +497,22 @@ void
 AtEOXact_LocalBuffers(bool isCommit)
 {
 #ifdef USE_ASSERT_CHECKING
-       if (assert_enabled)
+       if (assert_enabled && LocalRefCount)
        {
+               int                     RefCountErrors = 0;
                int                     i;
 
                for (i = 0; i < NLocBuffer; i++)
                {
-                       Assert(LocalRefCount[i] == 0);
+                       if (LocalRefCount[i] != 0)
+                       {
+                               Buffer  b = -i - 1;
+
+                               PrintBufferLeakWarning(b);
+                               RefCountErrors++;
+                       }
                }
+               Assert(RefCountErrors == 0);
        }
 #endif
 }
@@ -523,12 +531,20 @@ AtProcExit_LocalBuffers(void)
 #ifdef USE_ASSERT_CHECKING
        if (assert_enabled && LocalRefCount)
        {
+               int                     RefCountErrors = 0;
                int                     i;
 
                for (i = 0; i < NLocBuffer; i++)
                {
-                       Assert(LocalRefCount[i] == 0);
+                       if (LocalRefCount[i] != 0)
+                       {
+                               Buffer  b = -i - 1;
+
+                               PrintBufferLeakWarning(b);
+                               RefCountErrors++;
+                       }
                }
+               Assert(RefCountErrors == 0);
        }
 #endif
 }