From f43b705cb8799603d6f9f2ef950877b173bbeeef Mon Sep 17 00:00:00 2001 From: Bill Jin Date: Wed, 28 Jan 2026 23:41:24 +0000 Subject: [PATCH] MDEV-36676 Add debug function to print MEM_ROOT name Add dbug_print_memroot_name() to return the Performance Schema memory class name associated with a MEM_ROOT, for use from a debugger or in DBUG_PRINT. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc. --- storage/perfschema/pfs_instr_class.cc | 24 ++++++ storage/perfschema/pfs_instr_class.h | 3 + storage/perfschema/unittest/CMakeLists.txt | 2 +- .../perfschema/unittest/pfs_memroot_name-t.cc | 86 +++++++++++++++++++ 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 storage/perfschema/unittest/pfs_memroot_name-t.cc diff --git a/storage/perfschema/pfs_instr_class.cc b/storage/perfschema/pfs_instr_class.cc index 84cc452c022..c3a68793ad6 100644 --- a/storage/perfschema/pfs_instr_class.cc +++ b/storage/perfschema/pfs_instr_class.cc @@ -1591,6 +1591,30 @@ PFS_memory_class *sanitize_memory_class(PFS_memory_class *unsafe) SANITIZE_ARRAY_BODY(PFS_memory_class, memory_class_array, memory_class_max, unsafe); } + +#ifndef DBUG_OFF +/* + Return the name of a MEM_ROOT for use from a debugger. + @param root the MEM_ROOT to identify (may be NULL) + @return the instrument name, or "" +*/ +extern "C" +const char *dbug_print_memroot_name(MEM_ROOT *root) +{ + if (!root) + return ""; + + if (root->psi_key != PSI_NOT_INSTRUMENTED) + { + PFS_memory_class *klass= find_memory_class(root->psi_key); + if (klass != NULL && klass->m_name[0]) + return klass->m_name; + } + + return ""; +} +#endif + PFS_instr_class *find_table_class(uint index) { if (index == 1) diff --git a/storage/perfschema/pfs_instr_class.h b/storage/perfschema/pfs_instr_class.h index 25e635d09f1..e03795064f2 100644 --- a/storage/perfschema/pfs_instr_class.h +++ b/storage/perfschema/pfs_instr_class.h @@ -625,6 +625,9 @@ PFS_socket_class *find_socket_class(PSI_socket_key key); PFS_socket_class *sanitize_socket_class(PFS_socket_class *unsafe); PFS_memory_class *find_memory_class(PSI_memory_key key); PFS_memory_class *sanitize_memory_class(PFS_memory_class *unsafe); +#ifndef DBUG_OFF +extern "C" const char *dbug_print_memroot_name(struct st_mem_root *root); +#endif PFS_instr_class *find_idle_class(uint index); PFS_instr_class *sanitize_idle_class(PFS_instr_class *unsafe); PFS_instr_class *find_metadata_class(uint index); diff --git a/storage/perfschema/unittest/CMakeLists.txt b/storage/perfschema/unittest/CMakeLists.txt index 7323a19dc20..9c786de2692 100644 --- a/storage/perfschema/unittest/CMakeLists.txt +++ b/storage/perfschema/unittest/CMakeLists.txt @@ -36,5 +36,5 @@ ADD_DEPENDENCIES(pfs_server_stubs GenError) MY_ADD_TESTS(pfs_instr_class pfs_instr_class-oom pfs_instr pfs_instr-oom pfs_account-oom pfs_host-oom pfs_user-oom pfs_noop pfs - pfs_misc + pfs_misc pfs_memroot_name EXT "cc" LINK_LIBRARIES perfschema mysys pfs_server_stubs) diff --git a/storage/perfschema/unittest/pfs_memroot_name-t.cc b/storage/perfschema/unittest/pfs_memroot_name-t.cc new file mode 100644 index 00000000000..533f808c17d --- /dev/null +++ b/storage/perfschema/unittest/pfs_memroot_name-t.cc @@ -0,0 +1,86 @@ +/* Copyright (c) 2025, MariaDB Corporation. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stub_global_status_var.h" + +#ifndef DBUG_OFF + +void do_all_tests() +{ + MEM_ROOT root; + PFS_memory_key key; + const char *name; + int rc; + + rc= init_memory_class(5); + ok(rc == 0, "init_memory_class"); + + key= register_memory_class("test_memroot", 12, 0); + ok(key > 0, "test_memroot registered (key=%u)", key); + + /* NULL input */ + name= dbug_print_memroot_name(NULL); + ok(strcmp(name, "") == 0, "NULL returns ''"); + + /* Registered key returns name */ + init_alloc_root(key, &root, 1024, 0, MYF(0)); + name= dbug_print_memroot_name(&root); + ok(strcmp(name, "test_memroot") == 0, + "registered key returns 'test_memroot' (got '%s')", name); + free_root(&root, MYF(0)); + + /* PSI_NOT_INSTRUMENTED returns empty string */ + init_alloc_root(PSI_NOT_INSTRUMENTED, &root, 1024, 0, MYF(0)); + name= dbug_print_memroot_name(&root); + ok(strcmp(name, "") == 0, "PSI_NOT_INSTRUMENTED returns ''"); + free_root(&root, MYF(0)); + + /* Invalid key returns empty string */ + init_alloc_root(9999, &root, 1024, 0, MYF(0)); + name= dbug_print_memroot_name(&root); + ok(strcmp(name, "") == 0, "invalid key 9999 returns ''"); + free_root(&root, MYF(0)); + + cleanup_memory_class(); +} + +int main(int, char **) +{ + plan(6); + MY_INIT("pfs_memroot_name-t"); + do_all_tests(); + my_end(0); + return (exit_status()); +} + +#else /* DBUG_OFF */ + +int main(int, char **) +{ + plan(1); + ok(1, "dbug_print_memroot_name is a no-op in release builds"); + return (exit_status()); +} + +#endif /* DBUG_OFF */