Mark buffers as defined to Valgrind consistently.
authorPeter Geoghegan <pg@bowt.ie>
Sun, 19 Jul 2020 16:46:44 +0000 (09:46 -0700)
committerPeter Geoghegan <pg@bowt.ie>
Sun, 19 Jul 2020 16:46:44 +0000 (09:46 -0700)
Make PinBuffer() mark buffers as defined to Valgrind unconditionally,
including when the buffer header spinlock must be acquired.  Failure to
handle that case could lead to false positive reports from Valgrind.

This theoretically creates a risk that we'll mark buffers defined even
when external callers don't end up with a buffer pin.  That seems
perfectly acceptable, though, since in general we make no guarantees
about buffers that are unsafe to access being reliably marked as unsafe.

Oversight in commit 1e0dfd16, which added valgrind buffer access
instrumentation.

src/backend/storage/buffer/bufmgr.c

index 8ef073b3821b0d6d611ccabecfa6c9182435e2b1..83d91b14fb1c24752c19e807a33732f226398a32 100644 (file)
@@ -1636,11 +1636,13 @@ PinBuffer(BufferDesc *buf, BufferAccessStrategy strategy)
                result = (buf_state & BM_VALID) != 0;
 
                /*
-                * If we successfully acquired our first pin on this buffer
-                * within this backend, mark buffer contents defined
+                * Assume that we acquired a buffer pin for the purposes of
+                * Valgrind buffer client checks (even in !result case) to
+                * keep things simple.  Buffers that are unsafe to access are
+                * not generally guaranteed to be marked undefined in any
+                * case.
                 */
-               if (result)
-                   VALGRIND_MAKE_MEM_DEFINED(BufHdrGetBlock(buf), BLCKSZ);
+               VALGRIND_MAKE_MEM_DEFINED(BufHdrGetBlock(buf), BLCKSZ);
                break;
            }
        }