Skip to content
/ server Public
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions storage/perfschema/pfs_instr_class.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1591,6 +1591,52 @@ PFS_memory_class *sanitize_memory_class(PFS_memory_class *unsafe)
SANITIZE_ARRAY_BODY(PFS_memory_class, memory_class_array, memory_class_max, unsafe);
}

/**
Get the name of a memory instrumentation class by key.
This is a helper function for debug purposes.
@param key the instrument key
@return the instrument name, or NULL if not found
*/
const char *pfs_get_memory_class_name(PSI_memory_key key)
{
PFS_memory_class *memory_class= find_memory_class(key);
if (memory_class != NULL)
return memory_class->m_name;
return NULL;
}

#ifndef DBUG_OFF
/*
Print the name of a MEM_ROOT to stderr for use from a debugger.
@param root the MEM_ROOT to identify (may be NULL)
*/
extern "C"
void dbug_print_memroot_name(MEM_ROOT *root)
{
const char *name= NULL;

if (!root)
{
fprintf(stderr, "MEM_ROOT: NULL\n");
return;
}

if (root->psi_key != PSI_NOT_INSTRUMENTED)
{
PFS_memory_class *klass= find_memory_class(root->psi_key);
if (klass != NULL)
name= klass->m_name;
}

if (name && *name)
fprintf(stderr, "MEM_ROOT '%s' (%p) [key=%u]\n",
name, (void*)root, root->psi_key);
else
fprintf(stderr, "MEM_ROOT (%p) [key=%u]\n",
(void*)root, root->psi_key);
}
#endif

PFS_instr_class *find_table_class(uint index)
{
if (index == 1)
Expand Down
4 changes: 4 additions & 0 deletions storage/perfschema/pfs_instr_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,10 @@ 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);
const char *pfs_get_memory_class_name(PSI_memory_key key);
#ifndef DBUG_OFF
extern "C" void 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);
Expand Down
2 changes: 1 addition & 1 deletion storage/perfschema/unittest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
99 changes: 99 additions & 0 deletions storage/perfschema/unittest/pfs_memroot_name-t.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/* 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 <my_global.h>
#include <my_thread.h>
#include <pfs_instr.h>
#include <pfs_stat.h>
#include <pfs_global.h>
#include <pfs_instr_class.h>
#include <pfs_buffer_container.h>
#include <tap.h>

#include "stub_global_status_var.h"

#ifndef DBUG_OFF

void do_all_tests()
{
MEM_ROOT root;
PFS_memory_key key1, key2;
char *p;
int rc;

/* Initialize PFS memory class storage */
rc= init_memory_class(5);
ok(rc == 0, "init_memory_class");

/* Register test memory classes */
key1= register_memory_class("test_memroot", 12, 0);
ok(key1 > 0, "test_memroot registered (key=%u)", key1);

key2= register_memory_class("test_memroot_second", 19, 0);
ok(key2 > 0, "test_memroot_second registered (key=%u)", key2);

/* Test 1: NULL MEM_ROOT does not crash */
dbug_print_memroot_name(NULL);
ok(1, "NULL MEM_ROOT does not crash");

/* Test 2: MEM_ROOT with registered PSI key */
init_alloc_root(key1, &root, 1024, 0, MYF(0));
dbug_print_memroot_name(&root);
ok(1, "MEM_ROOT with registered PSI key does not crash");
free_root(&root, MYF(0));

/* Test 3: MEM_ROOT with PSI_NOT_INSTRUMENTED */
init_alloc_root(PSI_NOT_INSTRUMENTED, &root, 1024, 0, MYF(0));
dbug_print_memroot_name(&root);
ok(root.psi_key == PSI_NOT_INSTRUMENTED,
"PSI_NOT_INSTRUMENTED key is 0");
free_root(&root, MYF(0));

/* Test 4: MEM_ROOT with invalid/unregistered key */
init_alloc_root(9999, &root, 1024, 0, MYF(0));
dbug_print_memroot_name(&root);
ok(root.psi_key == 9999,
"Invalid key 9999 preserved and does not crash");
free_root(&root, MYF(0));

/* Test 5: MEM_ROOT with second key + allocation works */
init_alloc_root(key2, &root, 2048, 0, MYF(0));
dbug_print_memroot_name(&root);
p= (char *) alloc_root(&root, 100);
ok(p != NULL, "Allocation on MEM_ROOT with second key succeeds");
free_root(&root, MYF(0));

cleanup_memory_class();
}

int main(int, char **)
{
plan(8);
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 */