From a67d4ae602247067a367265acfe83d35a264f40c Mon Sep 17 00:00:00 2001 From: Peter Geoghegan Date: Tue, 6 Feb 2018 09:55:25 -0800 Subject: [PATCH] Mark logtape.c buffer's tail as defined to Valgrind. LogicalTapeFreeze() may write out its first block when it is dirty but not full, and then immediately read the first block back in from its BufFile as a BLCKSZ-width block. This can only occur in rare cases where next to no tuples were written out, which is only possible with parallel external tuplesorts. While this is pointless, it's also harmless. However, this can cause Valgrind to complain about a write() of uninitialized bytes, so mark the tail of the buffer as defined to Valgrind. Note that LogicalTapeFreeze() has always tended to write out some amount of garbage bytes. All that changed with parallel tuplesort is that the garbage is sometimes uninitialized memory rather than memory containing stale data from the tapeset. Per buildfarm members lousyjack and skink. Peter Geoghegan, based on a suggestion from Robert Haas and Tom Lane. --- src/backend/utils/sort/logtape.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/backend/utils/sort/logtape.c b/src/backend/utils/sort/logtape.c index 6b7c10b..1a02aba 100644 --- a/src/backend/utils/sort/logtape.c +++ b/src/backend/utils/sort/logtape.c @@ -86,6 +86,7 @@ #include "storage/buffile.h" #include "utils/builtins.h" #include "utils/logtape.h" +#include "utils/memdebug.h" #include "utils/memutils.h" /* @@ -874,6 +875,13 @@ LogicalTapeFreeze(LogicalTapeSet *lts, int tapenum, TapeShare *share) */ if (lt->dirty) { + /* + * Since garbage bytes at the tail of the buffer may remain + * uninitialized in the case of worker tuplesorts with very little + * input, mark the tail as defined + */ + VALGRIND_MAKE_MEM_DEFINED(lt->buffer + lt->nbytes, + lt->buffer_size - lt->nbytes); TapeBlockSetNBytes(lt->buffer, lt->nbytes); ltsWriteBlock(lts, lt->curBlockNumber, (void *) lt->buffer); lt->writing = false; -- 2.7.4