Skip to content

Commit 57dca6f

Browse files
committed
Fix explicit valgrind interaction in read_stream.c.
This is a back-patch of commits 2a8a006 and 2509b85 into REL_17_STABLE. It's doesn't fix any known live bug in PostgreSQL v17 itself, but an extension could in theory have used the per-buffer data feature and seen spurious errors under Valgrind. Discussion: https://postgr.es/m/CA%2BhUKG%2Bg6aXpi2FEHqeLOzE%2BxYw%3DOV%2B-N5jhOEnnV%2BF0USM9xA%40mail.gmail.com
1 parent 29cce27 commit 57dca6f

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

src/backend/storage/aio/read_stream.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,20 @@ read_stream_get_block(ReadStream *stream, void *per_buffer_data)
176176
if (blocknum != InvalidBlockNumber)
177177
stream->buffered_blocknum = InvalidBlockNumber;
178178
else
179+
{
180+
/*
181+
* Tell Valgrind that the per-buffer data is undefined. That replaces
182+
* the "noaccess" state that was set when the consumer moved past this
183+
* entry last time around the queue, and should also catch callbacks
184+
* that fail to initialize data that the buffer consumer later
185+
* accesses. On the first go around, it is undefined already.
186+
*/
187+
VALGRIND_MAKE_MEM_UNDEFINED(per_buffer_data,
188+
stream->per_buffer_data_size);
179189
blocknum = stream->callback(stream,
180190
stream->callback_private_data,
181191
per_buffer_data);
192+
}
182193

183194
return blocknum;
184195
}
@@ -687,8 +698,11 @@ read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
687698
}
688699

689700
#ifdef CLOBBER_FREED_MEMORY
690-
/* Clobber old buffer and per-buffer data for debugging purposes. */
701+
/* Clobber old buffer for debugging purposes. */
691702
stream->buffers[oldest_buffer_index] = InvalidBuffer;
703+
#endif
704+
705+
#if defined(CLOBBER_FREED_MEMORY) || defined(USE_VALGRIND)
692706

693707
/*
694708
* The caller will get access to the per-buffer data, until the next call.
@@ -697,11 +711,23 @@ read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
697711
* that is holding a dangling pointer to it.
698712
*/
699713
if (stream->per_buffer_data)
700-
wipe_mem(get_per_buffer_data(stream,
701-
oldest_buffer_index == 0 ?
702-
stream->queue_size - 1 :
703-
oldest_buffer_index - 1),
704-
stream->per_buffer_data_size);
714+
{
715+
void *per_buffer_data;
716+
717+
per_buffer_data = get_per_buffer_data(stream,
718+
oldest_buffer_index == 0 ?
719+
stream->queue_size - 1 :
720+
oldest_buffer_index - 1);
721+
722+
#if defined(CLOBBER_FREED_MEMORY)
723+
/* This also tells Valgrind the memory is "noaccess". */
724+
wipe_mem(per_buffer_data, stream->per_buffer_data_size);
725+
#elif defined(USE_VALGRIND)
726+
/* Tell it ourselves. */
727+
VALGRIND_MAKE_MEM_NOACCESS(per_buffer_data,
728+
stream->per_buffer_data_size);
729+
#endif
730+
}
705731
#endif
706732

707733
/* Pin transferred to caller. */

0 commit comments

Comments
 (0)