diff options
author | Jon Olav Hauglid <jon.hauglid@oracle.com> | 2012-10-04 16:15:13 +0200 |
---|---|---|
committer | Jon Olav Hauglid <jon.hauglid@oracle.com> | 2012-10-04 16:15:13 +0200 |
commit | bfba296d4084eab4b580cddc04e889ad2abdaeb2 (patch) | |
tree | cfc04b7846d4672b0ec88a3d9e95830cfc41ff31 /sql/sp_rcontext.h | |
parent | 30d35590a3bce929679cdc38d36fc67f7923a39e (diff) | |
download | mariadb-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/sp_rcontext.h')
-rw-r--r-- | sql/sp_rcontext.h | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 84d5a1227fe..c89ada3f3c8 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -58,6 +58,46 @@ typedef struct uint index; } sp_active_handler_t; + +class Sql_condition_info : public Sql_alloc +{ +public: + /** SQL error code. */ + uint m_sql_errno; + + /** Error level. */ + MYSQL_ERROR::enum_warning_level m_level; + + /** SQLSTATE. */ + char m_sql_state[SQLSTATE_LENGTH + 1]; + + /** Text message. */ + char m_message[MYSQL_ERRMSG_SIZE]; + + void set(uint sql_errno, const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg) + { + m_sql_errno= sql_errno; + m_level= level; + + memcpy(m_sql_state, sqlstate, SQLSTATE_LENGTH); + m_sql_state[SQLSTATE_LENGTH]= '\0'; + + strncpy(m_message, msg, MYSQL_ERRMSG_SIZE); + } + + void clear() + { + m_sql_errno= 0; + m_level= MYSQL_ERROR::WARN_LEVEL_ERROR; + + m_sql_state[0]= '\0'; + m_message[0]= '\0'; + } +}; + + /* This class is a runtime context of a Stored Routine. It is used in an execution and is intended to contain all dynamic objects (i.e. objects, which @@ -146,8 +186,7 @@ class sp_rcontext : public Sql_alloc MYSQL_ERROR::enum_warning_level level, const char *msg); - MYSQL_ERROR * - raised_condition() const; + Sql_condition_info *raised_condition() const; void push_hstack(uint h); @@ -232,7 +271,7 @@ private: SQL conditions caught by each handler. This is an array indexed by handler index. */ - MYSQL_ERROR *m_raised_conditions; + Sql_condition_info *m_raised_conditions; uint m_hcount; // Stack pointer for m_handler uint *m_hstack; // Return stack for continue handlers |