Skip to content

Commit

Permalink
MDEV-35828: Assertion fails in alloc_root() when memory causes it to …
Browse files Browse the repository at this point in the history
…call itself

(Variant 2: use stack for buffers)
my_malloc_size_cb_func() has a call to thd->alloc() to produce an error message.
thd->alloc() calls alloc_root(), so one can end up with this stack trace:

  alloc_root()
  THD::alloc()
  my_malloc_size_cb_func()
  my_malloc()
  alloc_root()

where alloc_root() calls itself. This is a problem, as alloc_root() is not
reenterable.

Fixed this by switching my_malloc_size_cb_func() to use space on the stack
instead.
  • Loading branch information
spetrunia committed Jan 15, 2025
1 parent 0fa1a7c commit a5174aa
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 13 deletions.
13 changes: 13 additions & 0 deletions mysql-test/main/errors.result
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,16 @@ Error 1327 Undeclared variable: foo
Error 1305 PROCEDURE P1 does not exist
drop procedure P1;
# End of 10.4 tests
#
# MDEV-35828: Assertion fails in alloc_root() when memory causes it to call itself
#
CREATE TEMPORARY TABLE t1 (a INT,b INT);
INSERT INTO t1 VALUES (1,1),(2,2);
SET
@tmp=@@max_session_mem_used,
max_session_mem_used=8192;
SELECT * FROM (t1 AS t2 LEFT JOIN t1 AS t3 USING (a)),t1;
ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement
DROP TABLE t1;
SET max_session_mem_used=@tmp;
# End of 10.6 tests
20 changes: 20 additions & 0 deletions mysql-test/main/errors.test
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,23 @@ show warnings;
drop procedure P1;

-- echo # End of 10.4 tests


--echo #
--echo # MDEV-35828: Assertion fails in alloc_root() when memory causes it to call itself
--echo #
CREATE TEMPORARY TABLE t1 (a INT,b INT);
INSERT INTO t1 VALUES (1,1),(2,2);

SET
@tmp=@@max_session_mem_used,
max_session_mem_used=8192;

--error ER_OPTION_PREVENTS_STATEMENT
SELECT * FROM (t1 AS t2 LEFT JOIN t1 AS t3 USING (a)),t1;

DROP TABLE t1;
SET max_session_mem_used=@tmp;


--echo # End of 10.6 tests
18 changes: 5 additions & 13 deletions sql/mysqld.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3513,22 +3513,14 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
LOCK_thd_kill here (the limit will be enforced on the next allocation).
*/
if (!mysql_mutex_trylock(&thd->LOCK_thd_kill)) {
char buf[50], *buf2;
char buf[50], buf2[256];
thd->set_killed_no_mutex(KILL_QUERY);
my_snprintf(buf, sizeof(buf), "--max-session-mem-used=%llu",
thd->variables.max_mem_used);
if ((buf2= (char*) thd->alloc(256)))
{
my_snprintf(buf2, 256,
ER_THD(thd, ER_OPTION_PREVENTS_STATEMENT), buf);
thd->set_killed_no_mutex(KILL_QUERY,
ER_OPTION_PREVENTS_STATEMENT, buf2);
}
else
{
thd->set_killed_no_mutex(KILL_QUERY, ER_OPTION_PREVENTS_STATEMENT,
"--max-session-mem-used");
}
my_snprintf(buf2, 256,
ER_THD(thd, ER_OPTION_PREVENTS_STATEMENT), buf);
thd->set_killed_no_mutex(KILL_QUERY,
ER_OPTION_PREVENTS_STATEMENT, buf2);
mysql_mutex_unlock(&thd->LOCK_thd_kill);
}
}
Expand Down

0 comments on commit a5174aa

Please sign in to comment.