Commit faf54ff9 authored by Alexey Kopytov's avatar Alexey Kopytov

Bug #56709: Memory leaks at running the 5.1 test suite

Fixed a number of memory leaks discovered by valgrind.

dbug/dbug.c:
  This is actually an addendum to the fix for bug #52629:
  
  - there is no point in limiting the fix to just global
  variables, session ones are also affected.
  - zero all fields when allocating a new 'state' structure so
  that FreeState() does not deal with unitialized data later.
  - add a check for a NULL pointer in DBUGCloseFile()
mysql-test/r/partition_error.result:
  Added a test case for bug #56709.
mysql-test/r/variables_debug.result:
  Added a test case for bug #56709.
mysql-test/t/partition_error.test:
  Added a test case for bug #56709.
mysql-test/t/variables_debug.test:
  Added a test case for bug #56709.
sql/item_timefunc.cc:
  There is no point in declaring 'value' as a member of
  Item_extract and dynamically allocating memory for it in
  Item_extract::fix_length_and_dec(), since this string is only
  used as a temporary storage in Item_extract::val_int().
sql/item_timefunc.h:
  Removed 'value' from the Item_extract class definition.
sql/sql_load.cc:
  - we may need to deallocate 'buffer' even when 'error' is
    non-zero in some cases, since 'error' is public, and there is
    external code modifying it.
  - assign NULL to buffer when deallocating it so that we don't
    do it twice in the destructor
  - there is no point in changing 'error' in the destructor.
parent 0c74cc0d
...@@ -455,12 +455,7 @@ static void DbugParse(CODE_STATE *cs, const char *control) ...@@ -455,12 +455,7 @@ static void DbugParse(CODE_STATE *cs, const char *control)
rel= control[0] == '+' || control[0] == '-'; rel= control[0] == '+' || control[0] == '-';
if ((!rel || (!stack->out_file && !stack->next))) if ((!rel || (!stack->out_file && !stack->next)))
{ {
/* /* Free memory associated with the state before resetting its members */
We need to free what's already in init_settings, because unlike
the thread related stack frames there's a chance that something
is in these variables already.
*/
if (stack == &init_settings)
FreeState(cs, stack, 0); FreeState(cs, stack, 0);
stack->flags= 0; stack->flags= 0;
stack->delay= 0; stack->delay= 0;
...@@ -1447,8 +1442,8 @@ static void PushState(CODE_STATE *cs) ...@@ -1447,8 +1442,8 @@ static void PushState(CODE_STATE *cs)
struct settings *new_malloc; struct settings *new_malloc;
new_malloc= (struct settings *) DbugMalloc(sizeof(struct settings)); new_malloc= (struct settings *) DbugMalloc(sizeof(struct settings));
bzero(new_malloc, sizeof(struct settings));
new_malloc->next= cs->stack; new_malloc->next= cs->stack;
new_malloc->out_file= NULL;
cs->stack= new_malloc; cs->stack= new_malloc;
} }
...@@ -1957,7 +1952,7 @@ static FILE *OpenProfile(CODE_STATE *cs, const char *name) ...@@ -1957,7 +1952,7 @@ static FILE *OpenProfile(CODE_STATE *cs, const char *name)
static void DBUGCloseFile(CODE_STATE *cs, FILE *fp) static void DBUGCloseFile(CODE_STATE *cs, FILE *fp)
{ {
if (fp != stderr && fp != stdout && fclose(fp) == EOF) if (fp != NULL && fp != stderr && fp != stdout && fclose(fp) == EOF)
{ {
pthread_mutex_lock(&THR_LOCK_dbug); pthread_mutex_lock(&THR_LOCK_dbug);
(void) fprintf(cs->stack->out_file, ERR_CLOSE, cs->process); (void) fprintf(cs->stack->out_file, ERR_CLOSE, cs->process);
......
...@@ -1008,4 +1008,14 @@ PARTITION p VALUES LESS THAN (1219089600), ...@@ -1008,4 +1008,14 @@ PARTITION p VALUES LESS THAN (1219089600),
PARTITION pmax VALUES LESS THAN MAXVALUE); PARTITION pmax VALUES LESS THAN MAXVALUE);
ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
DROP TABLE old; DROP TABLE old;
#
# Bug #56709: Memory leaks at running the 5.1 test suite
#
CREATE TABLE t1 (a TIMESTAMP NOT NULL PRIMARY KEY);
ALTER TABLE t1
PARTITION BY RANGE (EXTRACT(DAY FROM a)) (
PARTITION p VALUES LESS THAN (18),
PARTITION pmax VALUES LESS THAN MAXVALUE);
ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
DROP TABLE t1;
End of 5.1 tests End of 5.1 tests
...@@ -24,4 +24,17 @@ SELECT @@global.debug; ...@@ -24,4 +24,17 @@ SELECT @@global.debug;
@@global.debug @@global.debug
SET GLOBAL debug=@old_debug; SET GLOBAL debug=@old_debug;
#
# Bug #56709: Memory leaks at running the 5.1 test suite
#
SET @old_local_debug = @@debug;
SET @@debug='d,foo';
SELECT @@debug;
@@debug
d,foo
SET @@debug='';
SELECT @@debug;
@@debug
SET @@debug = @old_local_debug;
End of 5.1 tests End of 5.1 tests
...@@ -1252,4 +1252,18 @@ PARTITION pmax VALUES LESS THAN MAXVALUE); ...@@ -1252,4 +1252,18 @@ PARTITION pmax VALUES LESS THAN MAXVALUE);
DROP TABLE old; DROP TABLE old;
--echo #
--echo # Bug #56709: Memory leaks at running the 5.1 test suite
--echo #
CREATE TABLE t1 (a TIMESTAMP NOT NULL PRIMARY KEY);
--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
ALTER TABLE t1
PARTITION BY RANGE (EXTRACT(DAY FROM a)) (
PARTITION p VALUES LESS THAN (18),
PARTITION pmax VALUES LESS THAN MAXVALUE);
DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -25,4 +25,17 @@ SELECT @@global.debug; ...@@ -25,4 +25,17 @@ SELECT @@global.debug;
SET GLOBAL debug=@old_debug; SET GLOBAL debug=@old_debug;
--echo #
--echo # Bug #56709: Memory leaks at running the 5.1 test suite
--echo #
SET @old_local_debug = @@debug;
SET @@debug='d,foo';
SELECT @@debug;
SET @@debug='';
SELECT @@debug;
SET @@debug = @old_local_debug;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -2270,8 +2270,6 @@ void Item_extract::print(String *str, enum_query_type query_type) ...@@ -2270,8 +2270,6 @@ void Item_extract::print(String *str, enum_query_type query_type)
void Item_extract::fix_length_and_dec() void Item_extract::fix_length_and_dec()
{ {
value.alloc(32); // alloc buffer
maybe_null=1; // If wrong date maybe_null=1; // If wrong date
switch (int_type) { switch (int_type) {
case INTERVAL_YEAR: max_length=4; date_value=1; break; case INTERVAL_YEAR: max_length=4; date_value=1; break;
...@@ -2314,6 +2312,8 @@ longlong Item_extract::val_int() ...@@ -2314,6 +2312,8 @@ longlong Item_extract::val_int()
} }
else else
{ {
char buf[40];
String value(buf, sizeof(buf), &my_charset_bin);;
String *res= args[0]->val_str(&value); String *res= args[0]->val_str(&value);
if (!res || str_to_time_with_warn(res->ptr(), res->length(), &ltime)) if (!res || str_to_time_with_warn(res->ptr(), res->length(), &ltime))
{ {
......
...@@ -702,7 +702,6 @@ public: ...@@ -702,7 +702,6 @@ public:
class Item_extract :public Item_int_func class Item_extract :public Item_int_func
{ {
String value;
bool date_value; bool date_value;
public: public:
const interval_type int_type; // keep it public const interval_type int_type; // keep it public
......
...@@ -1116,6 +1116,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, ...@@ -1116,6 +1116,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
MYF(MY_WME))) MYF(MY_WME)))
{ {
my_free((uchar*) buffer,MYF(0)); /* purecov: inspected */ my_free((uchar*) buffer,MYF(0)); /* purecov: inspected */
buffer= NULL;
error=1; error=1;
} }
else else
...@@ -1142,13 +1143,10 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, ...@@ -1142,13 +1143,10 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
READ_INFO::~READ_INFO() READ_INFO::~READ_INFO()
{ {
if (!error) if (!error && need_end_io_cache)
{
if (need_end_io_cache)
::end_io_cache(&cache); ::end_io_cache(&cache);
my_free((uchar*) buffer,MYF(0));
error=1; my_free(buffer, MYF(MY_ALLOW_ZERO_PTR));
}
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment