Memory leaks in BufFileOpenShared()

Started by Antonin Houskaover 7 years ago8 messages
#1Antonin Houska
ah@cybertec.at

Memory is allocated twice for "file" and "files" variables. Possible fix:

diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c
index d8a18dd3dc..00f61748b3 100644
--- a/src/backend/storage/file/buffile.c
+++ b/src/backend/storage/file/buffile.c
@@ -277,10 +277,10 @@ BufFileCreateShared(SharedFileSet *fileset, const char *name)
 BufFile *
 BufFileOpenShared(SharedFileSet *fileset, const char *name)
 {
-       BufFile    *file = (BufFile *) palloc(sizeof(BufFile));
+       BufFile    *file;
        char            segment_name[MAXPGPATH];
        Size            capacity = 16;
-       File       *files = palloc(sizeof(File) * capacity);
+       File       *files;
        int                     nfiles = 0;

file = (BufFile *) palloc(sizeof(BufFile));

--
Antonin Houska
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26, A-2700 Wiener Neustadt
Web: https://www.cybertec-postgresql.com

#2Tatsuo Ishii
ishii@sraoss.co.jp
In reply to: Antonin Houska (#1)
Re: Memory leaks in BufFileOpenShared()

Memory is allocated twice for "file" and "files" variables. Possible fix:

diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c
index d8a18dd3dc..00f61748b3 100644
--- a/src/backend/storage/file/buffile.c
+++ b/src/backend/storage/file/buffile.c
@@ -277,10 +277,10 @@ BufFileCreateShared(SharedFileSet *fileset, const char *name)
BufFile *
BufFileOpenShared(SharedFileSet *fileset, const char *name)
{
-       BufFile    *file = (BufFile *) palloc(sizeof(BufFile));
+       BufFile    *file;
char            segment_name[MAXPGPATH];
Size            capacity = 16;
-       File       *files = palloc(sizeof(File) * capacity);
+       File       *files;
int                     nfiles = 0;

file = (BufFile *) palloc(sizeof(BufFile));

Good catch. Thanks.

Best regards,
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese:http://www.sraoss.co.jp

#3Antonin Houska
ah@cybertec.at
In reply to: Tatsuo Ishii (#2)
1 attachment(s)
Re: Memory leaks in BufFileOpenShared()

Now I see that BufFileCreateShared() has similar problem with file->name.

More generic problem I see is that the common initialization of BufFile is
repeated a few times. The attached patch tries to improve that (it also fixes
the duplicate allocation of file->name).

Tatsuo Ishii <ishii@sraoss.co.jp> wrote:

Memory is allocated twice for "file" and "files" variables. Possible fix:

diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c
index d8a18dd3dc..00f61748b3 100644
--- a/src/backend/storage/file/buffile.c
+++ b/src/backend/storage/file/buffile.c
@@ -277,10 +277,10 @@ BufFileCreateShared(SharedFileSet *fileset, const char *name)
BufFile *
BufFileOpenShared(SharedFileSet *fileset, const char *name)
{
-       BufFile    *file = (BufFile *) palloc(sizeof(BufFile));
+       BufFile    *file;
char            segment_name[MAXPGPATH];
Size            capacity = 16;
-       File       *files = palloc(sizeof(File) * capacity);
+       File       *files;
int                     nfiles = 0;

file = (BufFile *) palloc(sizeof(BufFile));

Good catch. Thanks.

Best regards,
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese:http://www.sraoss.co.jp

--
Antonin Houska
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26, A-2700 Wiener Neustadt
Web: https://www.cybertec-postgresql.com

Attachments:

buffile_refactor.patchtext/x-diffDownload
diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c
index d8a18dd3dc..e345d008b5 100644
--- a/src/backend/storage/file/buffile.c
+++ b/src/backend/storage/file/buffile.c
@@ -99,6 +99,7 @@ struct BufFile
 	char		buffer[BLCKSZ];
 };
 
+static BufFile *makeBufFileCommon(int nfiles);
 static BufFile *makeBufFile(File firstfile);
 static void extendBufFile(BufFile *file);
 static void BufFileLoadBuffer(BufFile *file);
@@ -106,21 +107,16 @@ static void BufFileDumpBuffer(BufFile *file);
 static int	BufFileFlush(BufFile *file);
 static File MakeNewSharedSegment(BufFile *file, int segment);
 
-
 /*
- * Create a BufFile given the first underlying physical file.
- * NOTE: caller must set isInterXact if appropriate.
+ * Create BufFile and perform the common initialization.
  */
 static BufFile *
-makeBufFile(File firstfile)
+makeBufFileCommon(int nfiles)
 {
 	BufFile    *file = (BufFile *) palloc(sizeof(BufFile));
 
-	file->numFiles = 1;
-	file->files = (File *) palloc(sizeof(File));
-	file->files[0] = firstfile;
-	file->offsets = (off_t *) palloc(sizeof(off_t));
-	file->offsets[0] = 0L;
+	file->numFiles = nfiles;
+	file->offsets = (off_t *) palloc0(sizeof(off_t) * nfiles);
 	file->isInterXact = false;
 	file->dirty = false;
 	file->resowner = CurrentResourceOwner;
@@ -128,6 +124,21 @@ makeBufFile(File firstfile)
 	file->curOffset = 0L;
 	file->pos = 0;
 	file->nbytes = 0;
+
+	return file;
+}
+
+/*
+ * Create a BufFile given the first underlying physical file.
+ * NOTE: caller must set isInterXact if appropriate.
+ */
+static BufFile *
+makeBufFile(File firstfile)
+{
+	BufFile    *file = makeBufFileCommon(1);
+
+	file->files = (File *) palloc(sizeof(File));
+	file->files[0] = firstfile;
 	file->readOnly = false;
 	file->fileset = NULL;
 	file->name = NULL;
@@ -246,23 +257,12 @@ BufFileCreateShared(SharedFileSet *fileset, const char *name)
 {
 	BufFile    *file;
 
-	file = (BufFile *) palloc(sizeof(BufFile));
+	file = makeBufFileCommon(1);
 	file->fileset = fileset;
 	file->name = pstrdup(name);
-	file->numFiles = 1;
 	file->files = (File *) palloc(sizeof(File));
 	file->files[0] = MakeNewSharedSegment(file, 0);
-	file->offsets = (off_t *) palloc(sizeof(off_t));
-	file->offsets[0] = 0L;
-	file->isInterXact = false;
-	file->dirty = false;
-	file->resowner = CurrentResourceOwner;
-	file->curFile = 0;
-	file->curOffset = 0L;
-	file->pos = 0;
-	file->nbytes = 0;
 	file->readOnly = false;
-	file->name = pstrdup(name);
 
 	return file;
 }
@@ -286,4 +286,3 @@
-	file = (BufFile *) palloc(sizeof(BufFile));
 	files = palloc(sizeof(File) * capacity);
 
 	/*
@@ -317,16 +316,8 @@ BufFileOpenShared(SharedFileSet *fileset, const char *name)
 				(errcode_for_file_access(),
 				 errmsg("could not open BufFile \"%s\"", name)));
 
-	file->numFiles = nfiles;
+	file = makeBufFileCommon(nfiles);
 	file->files = files;
-	file->offsets = (off_t *) palloc0(sizeof(off_t) * nfiles);
-	file->isInterXact = false;
-	file->dirty = false;
-	file->resowner = CurrentResourceOwner;	/* Unused, can't extend */
-	file->curFile = 0;
-	file->curOffset = 0L;
-	file->pos = 0;
-	file->nbytes = 0;
 	file->readOnly = true;		/* Can't write to files opened this way */
 	file->fileset = fileset;
 	file->name = pstrdup(name);
#4Tatsuo Ishii
ishii@sraoss.co.jp
In reply to: Antonin Houska (#3)
Re: Memory leaks in BufFileOpenShared()

Now I see that BufFileCreateShared() has similar problem with file->name.

Right.

More generic problem I see is that the common initialization of BufFile is
repeated a few times. The attached patch tries to improve that (it also fixes
the duplicate allocation of file->name).

The changes were made by this commit to add infrastructure for sharing
temporary files between backends, according to the author (Thomas
Munro).

https://git.postgresql.org/pg/commitdiff/dc6c4c9dc2a111519b76b22daaaac86c5608223b

Your proposal looks reasonable but I would like to hear from Thomas's
opinion as well.

Thomas?

Best regards,
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese:http://www.sraoss.co.jp

#5Antonin Houska
ah@cybertec.at
In reply to: Tatsuo Ishii (#4)
Re: Memory leaks in BufFileOpenShared()

Tatsuo Ishii <ishii@sraoss.co.jp> wrote:

The changes were made by this commit to add infrastructure for sharing
temporary files between backends, according to the author (Thomas
Munro).

https://git.postgresql.org/pg/commitdiff/dc6c4c9dc2a111519b76b22daaaac86c5608223b

Your proposal looks reasonable but I would like to hear from Thomas's
opinion as well.

o.k. He can actually have different feeling about details, e.g. if a new
function makeBufFileCommon() should be introduced or if makeBufFile() should
do the common settings. In the latter case, BufFileCreateTemp() would have to
do more work than it does now.

--
Antonin Houska
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26, A-2700 Wiener Neustadt
Web: https://www.cybertec-postgresql.com

#6Thomas Munro
thomas.munro@enterprisedb.com
In reply to: Antonin Houska (#5)
Re: Memory leaks in BufFileOpenShared()

On Fri, Jun 15, 2018 at 8:42 PM, Antonin Houska <ah@cybertec.at> wrote:

Tatsuo Ishii <ishii@sraoss.co.jp> wrote:

The changes were made by this commit to add infrastructure for sharing
temporary files between backends, according to the author (Thomas
Munro).

https://git.postgresql.org/pg/commitdiff/dc6c4c9dc2a111519b76b22daaaac86c5608223b

Your proposal looks reasonable but I would like to hear from Thomas's
opinion as well.

o.k. He can actually have different feeling about details, e.g. if a new
function makeBufFileCommon() should be introduced or if makeBufFile() should
do the common settings. In the latter case, BufFileCreateTemp() would have to
do more work than it does now.

Thanks for finding these accidental duplications, and to Ishii-san for
committing the fix. Oops.

+1 for this refactoring.

--
Thomas Munro
http://www.enterprisedb.com

#7Tatsuo Ishii
ishii@sraoss.co.jp
In reply to: Thomas Munro (#6)
Re: Memory leaks in BufFileOpenShared()

Hi Thomas,

On Fri, Jun 15, 2018 at 8:42 PM, Antonin Houska <ah@cybertec.at> wrote:

Tatsuo Ishii <ishii@sraoss.co.jp> wrote:

The changes were made by this commit to add infrastructure for sharing
temporary files between backends, according to the author (Thomas
Munro).

https://git.postgresql.org/pg/commitdiff/dc6c4c9dc2a111519b76b22daaaac86c5608223b

Your proposal looks reasonable but I would like to hear from Thomas's
opinion as well.

o.k. He can actually have different feeling about details, e.g. if a new
function makeBufFileCommon() should be introduced or if makeBufFile() should
do the common settings. In the latter case, BufFileCreateTemp() would have to
do more work than it does now.

Thanks for finding these accidental duplications, and to Ishii-san for
committing the fix. Oops.

+1 for this refactoring.

Thanks for confirming. I will go ahead commit/push the patch.

Best regards,
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese:http://www.sraoss.co.jp

#8Tatsuo Ishii
ishii@sraoss.co.jp
In reply to: Tatsuo Ishii (#7)
Re: Memory leaks in BufFileOpenShared()

Thanks for finding these accidental duplications, and to Ishii-san for
committing the fix. Oops.

+1 for this refactoring.

Thanks for confirming. I will go ahead commit/push the patch.

Done.

Best regards,
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese:http://www.sraoss.co.jp