summaryrefslogtreecommitdiff
path: root/sql/sql_signal.cc
diff options
context:
space:
mode:
authorJon Olav Hauglid <jon.hauglid@oracle.com>2012-10-04 16:15:13 +0200
committerJon Olav Hauglid <jon.hauglid@oracle.com>2012-10-04 16:15:13 +0200
commitbfba296d4084eab4b580cddc04e889ad2abdaeb2 (patch)
treecfc04b7846d4672b0ec88a3d9e95830cfc41ff31 /sql/sql_signal.cc
parent30d35590a3bce929679cdc38d36fc67f7923a39e (diff)
downloadmariadb-git-bfba296d4084eab4b580cddc04e889ad2abdaeb2.tar.gz
Bug#14640599 MEMORY LEAK WHEN EXECUTING STORED ROUTINE EXCEPTION HANDLER
When a SP handler is activated, memory is allocated to hold the MESSAGE_TEXT for the condition that caused the activation. The problem was that this memory was allocated on the MEM_ROOT belonging to the stored program. Since this MEM_ROOT is not freed until the stored program ends, a stored program that causes lots of handler activations can start using lots of memory. In 5.1 and earlier the problem did not exist as no MESSAGE_TEXT was allocated if a condition was raised with a handler present. However, this behavior lead to a number of other issues such as Bug#23032. This patch fixes the problem by allocating enough memory for the necessary MESSAGE_TEXTs in the SP MEM_ROOT when the SP starts and then re-using this memory each time a handler is activated. This is the 5.5 version of the patch.
Diffstat (limited to 'sql/sql_signal.cc')
-rw-r--r--sql/sql_signal.cc12
1 files changed, 9 insertions, 3 deletions
diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc
index 9910dfc924e..e0c2a96ac84 100644
--- a/sql/sql_signal.cc
+++ b/sql/sql_signal.cc
@@ -478,7 +478,7 @@ bool Signal_statement::execute(THD *thd)
bool Resignal_statement::execute(THD *thd)
{
- MYSQL_ERROR *signaled;
+ Sql_condition_info *signaled;
int result= TRUE;
DBUG_ENTER("Resignal_statement::execute");
@@ -491,15 +491,21 @@ bool Resignal_statement::execute(THD *thd)
DBUG_RETURN(result);
}
+ MYSQL_ERROR signaled_err(thd->mem_root);
+ signaled_err.set(signaled->m_sql_errno,
+ signaled->m_sql_state,
+ signaled->m_level,
+ signaled->m_message);
+
if (m_cond == NULL)
{
/* RESIGNAL without signal_value */
- result= raise_condition(thd, signaled);
+ result= raise_condition(thd, &signaled_err);
DBUG_RETURN(result);
}
/* RESIGNAL with signal_value */
- result= raise_condition(thd, signaled);
+ result= raise_condition(thd, &signaled_err);
DBUG_RETURN(result);
}