mariadb/mysql-test/main/sp-memory-leak.test

55 lines
939 B
Text
Raw Normal View History

MDEV-30680 Warning: Memory not freed: 280 on mangled query, LeakSanitizer: detected memory leaks The parser works as follows: The rule expr_lex returns a pointer to a newly created sp_expr_lex instance which is not linked to any MariaDB structures yet - it is pointed only from a Bison stack variable. The sp_expr_lex instance gets linked to other structures (such as sp_instr_jump_if_not) later, after scanning some following grammar. Problem before the fix: If a parse error happened immediately after expr_lex (before it got linked), the created sp_expr_lex value got lost causing a memory leak. Fix: - Using Bison's "destructor" directive to free the results of expr_lex on parse/oom errors. - Moving the call for LEX::cleanup_lex_after_parse_error() from MYSQL_YYABORT and yyerror inside parse_sql(). This is needed because Bison calls destructors after yyerror(), while it's important to delete the sp_expr_lex instance before LEX::cleanup_lex_after_parse_error(). The latter frees the memory root containing the sp_expr_lex instance. After this change the code block are executed in the following order: - yyerror() -- now only raises the error to DA (no cleanup done any more) - %destructor { delete $$; } <expr_lex> -- destructs the sp_expr_lex instance - LEX::cleanup_lex_after_parse_error() -- frees the memory root containing the sp_expr_lex instance - Removing the "delete sublex" related code from restore_lex(): - restore_lex() is called in most cases on success, when delete is not needed. - There is one place when restore_lex() is called on error: In sp_create_assignment_instr(). But in this case LEX::sp_lex_in_use is true anyway. The patch adds a new DBUG_ASSERT(lex->sp_lex_in_use) to guard this.
2023-05-15 10:41:31 +02:00
--echo #
--echo # MDEV-30680 Warning: Memory not freed: 280 on mangled query, LeakSanitizer: detected memory leaks
--echo #
DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
IF SCALAR() expected_THEN_here;
END
$$
DELIMITER ;$$
DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
WHILE SCALAR() expected_DO_here;
END
$$
DELIMITER ;$$
DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
REPEAT SELECT 1; UNTIL SCALAR() expected_END_here;
END
$$
DELIMITER ;$$
--echo #
--echo # MDEV-31578 DECLARE CURSOR: "Memory not freed: 280 bytes lost" on syntax error
--echo #
DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
DECLARE cur CURSOR (a INT) FOR SELECT a+1;
OPEN cur(sp_followed_by_syntax_error();
CLOSE cur;
END;
$$
DELIMITER ;$$
DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
DECLARE cur CURSOR (a INT) FOR SELECT a+1;
OPEN cur(1,sp_followed_by_syntax_error();
CLOSE cur;
END;
$$
DELIMITER ;$$