malloc: Smoke test for libmemusage
Checks
Context |
Check |
Description |
redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Build passed
|
redhat-pt-bot/TryBot-32bit |
success
|
Build for i686
|
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-arm |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 |
success
|
Test passed
|
redhat-pt-bot/TryBot-still_applies |
warning
|
Patch no longer applies to master
|
Commit Message
It was reported that libmemusage stopped working due to the
changes in commit aaad2123d68275acc0f061e ("elf: Fix slow tls
access after dlopen [BZ #19924]"). This shared object uses
non-static TLS and interposes malloc, so it runs into the
recursion issue worked around in commit 018f0fc3b818d4d1460a
("elf: Support recursive use of dynamic TLS in interposed
malloc") with certain applications. While the test added here
does not detect the recu issue, it is better than no test
at all.
---
malloc/Makefile | 16 ++++++++++-
malloc/tst-memusage.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+), 1 deletion(-)
base-commit: 4c09bd400b689f1af8e08103cff3d25e0cba51d4
@@ -54,6 +54,7 @@ tests := \
tst-memalign \
tst-memalign-2 \
tst-memalign-3 \
+ tst-memusage \
tst-obstack \
tst-posix_memalign \
tst-pvalloc \
@@ -279,8 +280,13 @@ extra-objs += memusagestat.o
# kernel interface headers, not something like libgd. So the simplest thing
# is to presume that the standard system headers will be ok for this file.
$(objpfx)memusagestat.o: sysincludes = # nothing
+
+ifeq ($(run-built-tests),yes)
+tests-special += $(objpfx)/tst-memusage-stat.out
endif
-endif
+
+endif # $(LIBGD)
+endif # !$(cross-compiling)
# Another goal which can be used to override the configure decision.
.PHONY: do-memusagestat
@@ -419,3 +425,11 @@ $(objpfx)tst-malloc-random.out: $(objpfx)tst-aligned_alloc-lib.so
tst-aligned-alloc-random-ENV = LD_PRELOAD=$(objpfx)tst-aligned_alloc-lib.so
tst-malloc-random-ENV = LD_PRELOAD=$(objpfx)tst-aligned_alloc-lib.so
+
+tst-memusage-ENV = LD_PRELOAD=$(objpfx)/libmemusage.so \
+ MEMUSAGE_OUTPUT=$(objpfx)/tst-memusage-output.data
+$(objpfx)tst-memusage: $(objpfx)/libmemusage.so
+$(objpfx)tst-memusage-stat.out: $(objpfx)tst-memusage.out $(objpfx)memusagestat
+ $(test-wrapper-env) $(run-program-env) $(rtld-prefix) \
+ $(objpfx)memusagestat $(objpfx)/tst-memusage-output.data >$@ 2>&1; \
+ $(evaluate-test)
new file mode 100644
@@ -0,0 +1,75 @@
+/* Smoke test for libmemusagestat.so.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+/* Do not use the test driver because this test needs to avoid
+ forking, to avoid exercising fork handling in libmemusage. */
+
+#include <array_length.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/xthread.h>
+#include <unistd.h>
+
+static void *allocations[1000];
+static unsigned int allocations_count;
+
+static void
+record (void *ptr)
+{
+ if (ptr == NULL)
+ FAIL_EXIT1 ("memory allocation failure");
+ if (allocations_count < array_length (allocations))
+ allocations[allocations_count++] = ptr;
+ else
+ FAIL_EXIT1 ("out of space for pointer tracking");
+}
+
+static void
+free_all (void)
+{
+ for (unsigned int i = 0; i < allocations_count; ++i)
+ free (allocations[i]);
+ allocations_count = 0;
+}
+
+static void *
+perform_allocations (void *ignored)
+{
+ for (int loops = 0; loops < 3; ++loops)
+ {
+ for (int i = 0; i < array_length (allocations); ++i)
+ record (malloc (1000));
+ free_all ();
+ for (int i = 0; i < array_length (allocations); ++i)
+ record (calloc (1000, 2));
+ free_all ();
+ for (int i = 0; i < array_length (allocations); ++i)
+ record (realloc (NULL, 4000));
+ free_all ();
+ }
+ return NULL;
+}
+
+int
+main (void)
+{
+ perform_allocations (NULL);
+ xpthread_join (xpthread_create (NULL, perform_allocations, NULL));
+}