1# Copyright (C) 1991-2022 Free Software Foundation, Inc. 2# This file is part of the GNU C Library. 3 4# The GNU C Library is free software; you can redistribute it and/or 5# modify it under the terms of the GNU Lesser General Public 6# License as published by the Free Software Foundation; either 7# version 2.1 of the License, or (at your option) any later version. 8 9# The GNU C Library is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12# Lesser General Public License for more details. 13 14# You should have received a copy of the GNU Lesser General Public 15# License along with the GNU C Library; if not, see 16# <https://www.gnu.org/licenses/>. 17 18# 19# Makefile for malloc routines 20# 21subdir := malloc 22 23include ../Makeconfig 24 25dist-headers := malloc.h 26headers := $(dist-headers) obstack.h mcheck.h 27tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ 28 tst-malloc-check tst-mallocfork tst-trim1 \ 29 tst-malloc-usable tst-realloc tst-reallocarray tst-posix_memalign \ 30 tst-pvalloc tst-pvalloc-fortify tst-memalign tst-mallopt \ 31 tst-malloc-backtrace tst-malloc-thread-exit \ 32 tst-malloc-thread-fail tst-malloc-fork-deadlock \ 33 tst-mallocfork2 \ 34 tst-mallocfork3 \ 35 tst-interpose-nothread \ 36 tst-interpose-thread \ 37 tst-alloc_buffer \ 38 tst-free-errno \ 39 tst-malloc-tcache-leak \ 40 tst-malloc_info tst-mallinfo2 \ 41 tst-malloc-too-large \ 42 tst-malloc-stats-cancellation \ 43 tst-tcfree1 tst-tcfree2 tst-tcfree3 \ 44 tst-safe-linking \ 45 tst-mallocalign1 \ 46 47tests-static := \ 48 tst-interpose-static-nothread \ 49 tst-interpose-static-thread 50 51# Test for the malloc_set_state symbol removed in glibc 2.25. 52ifeq ($(have-GLIBC_2.23)$(build-shared),yesyes) 53tests += tst-mallocstate tst-compathooks-off tst-compathooks-on 54endif 55 56tests-internal := tst-scratch_buffer 57 58# The dynarray framework is only available inside glibc. 59tests-internal += \ 60 tst-dynarray \ 61 tst-dynarray-fail \ 62 tst-dynarray-at-fail \ 63 64ifneq (no,$(have-tunables)) 65tests += tst-malloc-usable-tunables tst-mxfast 66endif 67 68tests += $(tests-static) 69test-srcs = tst-mtrace 70 71# These tests either are run with MALLOC_CHECK_=3 by default or do not work 72# with MALLOC_CHECK_=3 because they expect a specific failure. 73tests-exclude-malloc-check = tst-malloc-check tst-malloc-usable \ 74 tst-mxfast tst-safe-linking \ 75 tst-compathooks-off tst-compathooks-on 76 77# Run all tests with MALLOC_CHECK_=3 78tests-malloc-check = $(filter-out $(tests-exclude-malloc-check) \ 79 $(tests-static),$(tests)) 80 81# Run all tests with GLIBC_TUNABLES=glibc.malloc.hugetlb={1,2} which check 82# the Transparent Huge Pages support (1) or automatic huge page support (2). 83# We need exclude some tests that define the ENV vars. 84tests-exclude-hugetlb1 = \ 85 tst-compathooks-off \ 86 tst-compathooks-on \ 87 tst-interpose-nothread \ 88 tst-interpose-thread \ 89 tst-interpose-static-nothread \ 90 tst-interpose-static-thread \ 91 tst-malloc-usable \ 92 tst-malloc-usable-tunables \ 93 tst-mallocstate 94# The tst-free-errno relies on the used malloc page size to mmap an 95# overlapping region. 96tests-exclude-hugetlb2 = \ 97 $(tests-exclude-hugetlb1) \ 98 tst-free-errno 99tests-malloc-hugetlb1 = \ 100 $(filter-out $(tests-exclude-hugetlb1), $(tests)) 101tests-malloc-hugetlb2 = \ 102 $(filter-out $(tests-exclude-hugetlb2), $(tests)) 103 104# -lmcheck needs __malloc_initialize_hook, which was deprecated in 2.24. 105ifeq ($(have-GLIBC_2.23)$(build-shared),yesyes) 106# Tests that don't play well with mcheck. They are either bugs in mcheck or 107# the tests expect specific internal behavior that is changed due to linking to 108# libmcheck.a. 109tests-exclude-mcheck = tst-mallocstate \ 110 tst-safe-linking \ 111 tst-malloc-backtrace \ 112 tst-malloc-fork-deadlock \ 113 tst-malloc-stats-cancellation \ 114 tst-malloc-tcache-leak \ 115 tst-malloc-thread-exit \ 116 tst-malloc-thread-fail \ 117 tst-malloc-usable-tunables \ 118 tst-malloc_info \ 119 tst-compathooks-off tst-compathooks-on \ 120 tst-mxfast 121 122tests-mcheck = $(filter-out $(tests-exclude-mcheck) $(tests-static), $(tests)) 123endif 124 125routines = malloc mcheck mtrace obstack reallocarray \ 126 scratch_buffer_dupfree \ 127 scratch_buffer_grow scratch_buffer_grow_preserve \ 128 scratch_buffer_set_array_size \ 129 dynarray_at_failure \ 130 dynarray_emplace_enlarge \ 131 dynarray_finalize \ 132 dynarray_resize \ 133 dynarray_resize_clear \ 134 alloc_buffer_alloc_array \ 135 alloc_buffer_allocate \ 136 alloc_buffer_copy_bytes \ 137 alloc_buffer_copy_string \ 138 alloc_buffer_create_failure \ 139 140install-lib := libmcheck.a 141non-lib.a := libmcheck.a 142 143# Additional libraries. 144extra-libs = libmemusage libc_malloc_debug 145extra-libs-others = $(extra-libs) 146 147# Helper objects for some tests. 148extra-test-objs += \ 149 tst-interpose-aux-nothread.o \ 150 tst-interpose-aux-thread.o \ 151 152test-extras = \ 153 tst-interpose-aux-nothread \ 154 tst-interpose-aux-thread \ 155 156libmemusage-routines = memusage 157libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes)) 158 159libc_malloc_debug-routines = malloc-debug $(sysdep_malloc_debug_routines) 160libc_malloc_debug-inhibit-o = $(filter-out .os,$(object-suffixes)) 161 162$(objpfx)tst-malloc-backtrace: $(shared-thread-library) 163$(objpfx)tst-malloc-thread-exit: $(shared-thread-library) 164$(objpfx)tst-malloc-thread-fail: $(shared-thread-library) 165$(objpfx)tst-mallocfork3: $(shared-thread-library) 166$(objpfx)tst-mallocfork3-mcheck: $(shared-thread-library) 167$(objpfx)tst-malloc-fork-deadlock: $(shared-thread-library) 168$(objpfx)tst-malloc-stats-cancellation: $(shared-thread-library) 169$(objpfx)tst-malloc-backtrace-mcheck: $(shared-thread-library) 170$(objpfx)tst-malloc-thread-exit-mcheck: $(shared-thread-library) 171$(objpfx)tst-malloc-thread-fail-mcheck: $(shared-thread-library) 172$(objpfx)tst-malloc-fork-deadlock-mcheck: $(shared-thread-library) 173$(objpfx)tst-malloc-stats-cancellation-mcheck: $(shared-thread-library) 174$(objpfx)tst-mallocfork3-malloc-check: $(shared-thread-library) 175$(objpfx)tst-malloc-backtrace-malloc-check: $(shared-thread-library) 176$(objpfx)tst-malloc-thread-exit-malloc-check: $(shared-thread-library) 177$(objpfx)tst-malloc-thread-fail-malloc-check: $(shared-thread-library) 178$(objpfx)tst-malloc-fork-deadlock-malloc-check: $(shared-thread-library) 179$(objpfx)tst-malloc-stats-cancellation-malloc-check: $(shared-thread-library) 180$(objpfx)tst-malloc-thread-exit-malloc-hugetlb1: $(shared-thread-library) 181$(objpfx)tst-malloc-thread-fail-malloc-hugetlb1: $(shared-thread-library) 182$(objpfx)tst-mallocfork2-malloc-hugetlb1: $(shared-thread-library) 183$(objpfx)tst-mallocfork3-malloc-hugetlb1: $(shared-thread-library) 184$(objpfx)tst-malloc-fork-deadlock-malloc-hugetlb1: $(shared-thread-library) 185$(objpfx)tst-malloc-stats-cancellation-malloc-hugetlb1: $(shared-thread-library) 186$(objpfx)tst-malloc-thread-exit-malloc-hugetlb2: $(shared-thread-library) 187$(objpfx)tst-malloc-thread-fail-malloc-hugetlb2: $(shared-thread-library) 188$(objpfx)tst-mallocfork2-malloc-hugetlb2: $(shared-thread-library) 189$(objpfx)tst-mallocfork3-malloc-hugetlb2: $(shared-thread-library) 190$(objpfx)tst-malloc-fork-deadlock-malloc-hugetlb2: $(shared-thread-library) 191$(objpfx)tst-malloc-stats-cancellation-malloc-hugetlb2: $(shared-thread-library) 192 193# These should be removed by `make clean'. 194extra-objs = mcheck-init.o libmcheck.a 195others-extras = mcheck-init.o 196 197# Include the cleanup handler. 198aux := set-freeres thread-freeres 199 200# The Perl script to analyze the output of the mtrace functions. 201ifneq ($(PERL),no) 202install-bin-script = mtrace 203generated += mtrace 204 205# The Perl script will print addresses and to do this nicely we must know 206# whether we are on a 32 or 64 bit machine. 207ifneq ($(findstring wordsize-32,$(config-sysdirs)),) 208address-width=10 209else 210address-width=18 211endif 212endif 213 214# Unless we get a test for the availability of libgd which also works 215# for cross-compiling we disable the memusagestat generation in this 216# situation. 217ifneq ($(cross-compiling),yes) 218# If the gd library is available we build the `memusagestat' program. 219ifneq ($(LIBGD),no) 220others: $(objpfx)memusage 221others += memusagestat 222install-bin = memusagestat 223install-bin-script += memusage 224generated += memusagestat memusage 225extra-objs += memusagestat.o 226 227# The configure.ac check for libgd and its headers did not use $SYSINCLUDES. 228# The directory specified by --with-headers usually contains only the basic 229# kernel interface headers, not something like libgd. So the simplest thing 230# is to presume that the standard system headers will be ok for this file. 231$(objpfx)memusagestat.o: sysincludes = # nothing 232endif 233endif 234 235# Another goal which can be used to override the configure decision. 236.PHONY: do-memusagestat 237do-memusagestat: $(objpfx)memusagestat 238 239memusagestat-modules = memusagestat 240 241cpp-srcs-left := $(memusagestat-modules) 242lib := memusagestat 243include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left)) 244 245LDLIBS-memusagestat = $(libgd-LDFLAGS) -lgd -lpng -lz -lm 246 247ifeq ($(run-built-tests),yes) 248ifeq (yes,$(build-shared)) 249ifneq ($(PERL),no) 250tests-special += $(objpfx)tst-mtrace.out 251tests-special += $(objpfx)tst-dynarray-mem.out 252tests-special += $(objpfx)tst-dynarray-fail-mem.out 253endif 254endif 255endif 256 257include ../Rules 258 259CFLAGS-mcheck-init.c += $(PIC-ccflag) 260CFLAGS-obstack.c += $(uses-callbacks) 261 262$(objpfx)libmcheck.a: $(objpfx)mcheck-init.o 263 -rm -f $@ 264 $(patsubst %/,cd % &&,$(objpfx)) \ 265 $(LN_S) $(<F) $(@F) 266 267lib: $(objpfx)libmcheck.a 268 269ifeq ($(run-built-tests),yes) 270ifeq (yes,$(build-shared)) 271ifneq ($(PERL),no) 272$(objpfx)tst-mtrace.out: tst-mtrace.sh $(objpfx)tst-mtrace 273 $(SHELL) $< $(common-objpfx) '$(test-program-prefix-before-env)' \ 274 '$(run-program-env)' '$(test-program-prefix-after-env)'; \ 275 $(evaluate-test) 276endif 277endif 278endif 279 280tst-malloc-check-ENV = MALLOC_CHECK_=3 \ 281 LD_PRELOAD=$(objpfx)/libc_malloc_debug.so 282tst-malloc-usable-ENV = MALLOC_CHECK_=3 \ 283 LD_PRELOAD=$(objpfx)/libc_malloc_debug.so 284tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \ 285 LD_PRELOAD=$(objpfx)/libc_malloc_debug.so 286 287tst-mxfast-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=0:glibc.malloc.mxfast=0 288 289CPPFLAGS-malloc-debug.c += -DUSE_TCACHE=0 290ifeq ($(experimental-malloc),yes) 291CPPFLAGS-malloc.c += -DUSE_TCACHE=1 292else 293CPPFLAGS-malloc.c += -DUSE_TCACHE=0 294endif 295# Uncomment this for test releases. For public releases it is too expensive. 296#CPPFLAGS-malloc.o += -DMALLOC_DEBUG=1 297 298sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,') 299 300$(objpfx)mtrace: mtrace.pl 301 rm -f $@.new 302 sed -e 's|@PERL@|$(PERL)|' -e 's|@XXX@|$(address-width)|' \ 303 -e 's|@VERSION@|$(version)|' \ 304 -e 's|@PKGVERSION@|$(PKGVERSION)|' \ 305 -e 's|@REPORT_BUGS_TO@|$(REPORT_BUGS_TO)|' $^ > $@.new \ 306 && rm -f $@ && mv $@.new $@ && chmod +x $@ 307 308$(objpfx)memusage: memusage.sh 309 rm -f $@.new 310 sed -e 's|@VERSION@|$(version)|' -e 's|@SLIBDIR@|$(sLIBdir)|' \ 311 -e 's|@BINDIR@|$(bindir)|' -e 's|@PKGVERSION@|$(PKGVERSION)|' \ 312 -e 's|@REPORT_BUGS_TO@|$(REPORT_BUGS_TO)|' $^ > $@.new \ 313 && rm -f $@ && mv $@.new $@ && chmod +x $@ 314 315# Compile the tests with a flag which suppresses the mallopt call in 316# the test skeleton. 317$(tests:%=$(objpfx)%.o): CPPFLAGS += -DTEST_NO_MALLOPT 318 319$(objpfx)tst-interpose-nothread: $(objpfx)tst-interpose-aux-nothread.o 320$(objpfx)tst-interpose-nothread-mcheck: $(objpfx)tst-interpose-aux-nothread.o 321$(objpfx)tst-interpose-nothread-malloc-check: \ 322 $(objpfx)tst-interpose-aux-nothread.o 323$(objpfx)tst-interpose-thread: \ 324 $(objpfx)tst-interpose-aux-thread.o $(shared-thread-library) 325$(objpfx)tst-interpose-thread-mcheck: \ 326 $(objpfx)tst-interpose-aux-thread.o $(shared-thread-library) 327$(objpfx)tst-interpose-thread-malloc-check: \ 328 $(objpfx)tst-interpose-aux-thread.o $(shared-thread-library) 329$(objpfx)tst-interpose-static-nothread: $(objpfx)tst-interpose-aux-nothread.o 330$(objpfx)tst-interpose-static-thread: \ 331 $(objpfx)tst-interpose-aux-thread.o $(static-thread-library) 332 333tst-dynarray-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray.mtrace \ 334 LD_PRELOAD=$(objpfx)libc_malloc_debug.so 335$(objpfx)tst-dynarray-mem.out: $(objpfx)tst-dynarray.out 336 $(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray.mtrace > $@; \ 337 $(evaluate-test) 338 339tst-dynarray-fail-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray-fail.mtrace \ 340 LD_PRELOAD=$(objpfx)libc_malloc_debug.so 341$(objpfx)tst-dynarray-fail-mem.out: $(objpfx)tst-dynarray-fail.out 342 $(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray-fail.mtrace > $@; \ 343 $(evaluate-test) 344 345$(objpfx)tst-malloc-tcache-leak: $(shared-thread-library) 346$(objpfx)tst-malloc_info: $(shared-thread-library) 347$(objpfx)tst-mallocfork2: $(shared-thread-library) 348$(objpfx)tst-malloc-tcache-leak-mcheck: $(shared-thread-library) 349$(objpfx)tst-malloc_info-mcheck: $(shared-thread-library) 350$(objpfx)tst-mallocfork2-mcheck: $(shared-thread-library) 351$(objpfx)tst-malloc-tcache-leak-malloc-check: $(shared-thread-library) 352$(objpfx)tst-malloc_info-malloc-check: $(shared-thread-library) 353$(objpfx)tst-mallocfork2-malloc-check: $(shared-thread-library) 354$(objpfx)tst-malloc-tcache-leak-malloc-hugetlb1: $(shared-thread-library) 355$(objpfx)tst-malloc-tcache-leak-malloc-hugetlb2: $(shared-thread-library) 356$(objpfx)tst-malloc_info-malloc-hugetlb1: $(shared-thread-library) 357$(objpfx)tst-malloc_info-malloc-hugetlb2: $(shared-thread-library) 358 359tst-compathooks-on-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so 360tst-compathooks-on-mcheck-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so 361tst-compathooks-on-malloc-check-ENV = \ 362 LD_PRELOAD=$(objpfx)libc_malloc_debug.so 363tst-mallocstate-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so 364tst-mallocstate-malloc-check-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so 365 366# The test needs malloc_get_state/malloc_set_state which is in 367# libc_malloc_debug.so. 368$(objpfx)tst-mallocstate: $(objpfx)libc_malloc_debug.so 369$(objpfx)tst-mallocstate-malloc-check: $(objpfx)libc_malloc_debug.so 370