From dcafdbcde1baf256891be6af77868b84889b435d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 15 Mar 2013 12:26:26 -0400 Subject: [PATCH] Improve error reporting in code that checks for buffer refcount leaks. 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 | 24 ++++++++++++++++++------ src/backend/storage/buffer/localbuf.c | 22 +++++++++++++++++++--- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index ea7d469f2f..0b4c2ed0a0 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -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 diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c index 30dc8098ed..03055c96d8 100644 --- a/src/backend/storage/buffer/localbuf.c +++ b/src/backend/storage/buffer/localbuf.c @@ -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 } -- GitLab