From: | "Zhang, Jie" <zhangjie2(at)cn(dot)fujitsu(dot)com> |
---|---|
To: | "pgsql-hackers(at)lists(dot)postgresql(dot)org" <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
Cc: | "Zhang, Jie" <zhangjie2(at)cn(dot)fujitsu(dot)com> |
Subject: | [PATCH] memory leak in ecpglib |
Date: | 2019-06-10 00:53:49 |
Message-ID: | 1396E95157071C4EBBA51892C5368521017F311A7C@G08CNEXMBPEKD02.g08.fujitsu.local |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi all
Memory leaks occur when the ecpg_update_declare_statement() is called the second time.
FILE:postgresql\src\interfaces\ecpg\ecpglib\prepare.c
void
ecpg_update_declare_statement(const char *declared_name, const char *cursor_name, const int lineno)
{
struct declared_statement *p = NULL;
if (!declared_name || !cursor_name)
return;
/* Find the declared node by declared name */
p = ecpg_find_declared_statement(declared_name);
if (p)
p->cursor_name = ecpg_strdup(cursor_name, lineno); ★
}
ecpg_strdup() returns a pointer to a null-terminated byte string, which is a duplicate of the string pointed to by str.
The memory obtained is done dynamically using malloc and hence it can be freed using free().
When the ecpg_update_declare_statement() is called for the second time,
the memory allocated for p->cursor_name is not freed.
For example:
EXEC SQL BEGIN DECLARE SECTION;
char *selectString = "SELECT * FROM foo;";
int FooBar;
char DooDad[17];
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO postgres(at)localhost:5432 AS con1 USER postgres;
EXEC SQL AT con1 DECLARE stmt_1 STATEMENT;
EXEC SQL AT con1 PREPARE stmt_1 FROM :selectString;
EXEC SQL AT con1 DECLARE cur_1 CURSOR FOR stmt_1; //★1 ECPGopen() --> ecpg_update_declare_statement()
EXEC SQL AT con1 OPEN cur_1;
EXEC SQL AT con1 DECLARE cur_2 CURSOR FOR stmt_1; //★2 ECPGopen() --> ecpg_update_declare_statement()
EXEC SQL AT con1 OPEN cur_2; Memory leaks
EXEC SQL FETCH cur_2 INTO:FooBar, :DooDad;
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
We should free p->cursor_name before p->cursor_name = ecpg_strdup(cursor_name, lineno).
#############################################################################
if(p->cursor_name)
ecpg_free(p->cursor_name);
p->cursor_name = ecpg_strdup(cursor_name,lineno);
###########################################################################
Here is a patch.
Best Regards!
Attachment | Content-Type | Size |
---|---|---|
ecpglib.patch | application/octet-stream | 544 bytes |
From | Date | Subject | |
---|---|---|---|
Next Message | Zhang, Jie | 2019-06-10 01:58:48 | [PATCH] Fix potential memoryleak in guc.c |
Previous Message | Tom Lane | 2019-06-10 00:33:10 | Re: Avoiding deadlock errors in CREATE INDEX CONCURRENTLY |