Commit d665cd9b by Tom de Vries Committed by Tom de Vries

[libbacktrace] Add allocfail.sh test-case

Add test-case that forces alloc.c functions to fail, and check whether fail
handling is robust.

This is the test-case for "[libbacktrace] Fix segfault upon allocation
failure".  Without that patch, this test-case fails like this:
...
allocfail.sh: line 71: 26041 Segmentation fault      (core dumped) \
  ./allocfail $i > /dev/null 2>&1
Unallowed fail found: 13
FAIL allocfail.sh (exit status: 1)
...

This is a seperate patch because the test-case is nontrivial.

Bootstrapped and reg-tested on x86_64.

2018-12-12  Tom de Vries  <tdevries@suse.de>

	* Makefile.am (TESTS): Add allocfail.sh.
	(check_PROGRAMS): Add allocfail.
	* Makefile.in: Regenerate.
	* instrumented_alloc.c: New file.  Redefine malloc and realloc.
	Include alloc.c.
	* allocfail.c: New file.
	* allocfail.sh: New file.

From-SVN: r267054
parent bf4eca2e
2018-12-12 Tom de Vries <tdevries@suse.de>
* Makefile.am (TESTS): Add allocfail.sh.
(check_PROGRAMS): Add allocfail.
* Makefile.in: Regenerate.
* instrumented_alloc.c: New file. Redefine malloc and realloc.
Include alloc.c.
* allocfail.c: New file.
* allocfail.sh: New file.
2018-11-30 Tom de Vries <tdevries@suse.de>
* Makefile.am (check_PROGRAMS): Add test_elf, test_xcoff_32,
......
......@@ -145,6 +145,26 @@ unittest_alloc_LDADD = libbacktrace_alloc.la
check_PROGRAMS += unittest_alloc
check_LTLIBRARIES += libbacktrace_instrumented_alloc.la
libbacktrace_instrumented_alloc_la_SOURCES = $(libbacktrace_la_SOURCES)
libbacktrace_instrumented_alloc_la_LIBADD = $(BACKTRACE_FILE) $(FORMAT_FILE) \
read.lo instrumented_alloc.lo
libbacktrace_instrumented_alloc_la_DEPENDENCIES = \
$(libbacktrace_instrumented_alloc_la_LIBADD)
instrumented_alloc.lo: alloc.c
allocfail_SOURCES = allocfail.c testlib.c
allocfail_LDADD = libbacktrace_instrumented_alloc.la
check_PROGRAMS += allocfail
allocfail.sh: allocfail
TESTS += allocfail.sh
btest_SOURCES = btest.c testlib.c
btest_CFLAGS = $(AM_CFLAGS) -g -O
btest_LDADD = libbacktrace.la
......
......@@ -123,13 +123,14 @@ target_triplet = @target@
check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3)
@NATIVE_TRUE@am__append_1 = test_elf test_xcoff_32 test_xcoff_64 \
@NATIVE_TRUE@ test_pecoff test_unknown unittest unittest_alloc \
@NATIVE_TRUE@ btest btest_alloc stest stest_alloc ztest \
@NATIVE_TRUE@ ztest_alloc edtest edtest_alloc
@HAVE_ZLIB_TRUE@@NATIVE_TRUE@am__append_2 = -lz
@NATIVE_TRUE@ allocfail btest btest_alloc stest stest_alloc \
@NATIVE_TRUE@ ztest ztest_alloc edtest edtest_alloc
@NATIVE_TRUE@am__append_2 = allocfail.sh
@HAVE_ZLIB_TRUE@@NATIVE_TRUE@am__append_3 = -lz
@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__append_4 = ttest ttest_alloc
@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_5 = dtest
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__append_6 = ctestg ctesta \
@HAVE_ZLIB_TRUE@@NATIVE_TRUE@am__append_4 = -lz
@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__append_5 = ttest ttest_alloc
@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_6 = dtest
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__append_7 = ctestg ctesta \
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctestg_alloc \
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta_alloc
subdir = .
......@@ -169,6 +170,11 @@ am__objects_1 = atomic.lo dwarf.lo fileline.lo posix.lo print.lo \
@NATIVE_TRUE@am_libbacktrace_alloc_la_OBJECTS = $(am__objects_1)
libbacktrace_alloc_la_OBJECTS = $(am_libbacktrace_alloc_la_OBJECTS)
@NATIVE_TRUE@am_libbacktrace_alloc_la_rpath =
@NATIVE_TRUE@am_libbacktrace_instrumented_alloc_la_OBJECTS = \
@NATIVE_TRUE@ $(am__objects_1)
libbacktrace_instrumented_alloc_la_OBJECTS = \
$(am_libbacktrace_instrumented_alloc_la_OBJECTS)
@NATIVE_TRUE@am_libbacktrace_instrumented_alloc_la_rpath =
@NATIVE_TRUE@am_libbacktrace_noformat_la_OBJECTS = $(am__objects_1)
libbacktrace_noformat_la_OBJECTS = \
$(am_libbacktrace_noformat_la_OBJECTS)
......@@ -176,11 +182,11 @@ libbacktrace_noformat_la_OBJECTS = \
@NATIVE_TRUE@am__EXEEXT_1 = test_elf$(EXEEXT) test_xcoff_32$(EXEEXT) \
@NATIVE_TRUE@ test_xcoff_64$(EXEEXT) test_pecoff$(EXEEXT) \
@NATIVE_TRUE@ test_unknown$(EXEEXT) unittest$(EXEEXT) \
@NATIVE_TRUE@ unittest_alloc$(EXEEXT) btest$(EXEEXT) \
@NATIVE_TRUE@ btest_alloc$(EXEEXT) stest$(EXEEXT) \
@NATIVE_TRUE@ stest_alloc$(EXEEXT) ztest$(EXEEXT) \
@NATIVE_TRUE@ ztest_alloc$(EXEEXT) edtest$(EXEEXT) \
@NATIVE_TRUE@ edtest_alloc$(EXEEXT)
@NATIVE_TRUE@ unittest_alloc$(EXEEXT) allocfail$(EXEEXT) \
@NATIVE_TRUE@ btest$(EXEEXT) btest_alloc$(EXEEXT) \
@NATIVE_TRUE@ stest$(EXEEXT) stest_alloc$(EXEEXT) \
@NATIVE_TRUE@ ztest$(EXEEXT) ztest_alloc$(EXEEXT) \
@NATIVE_TRUE@ edtest$(EXEEXT) edtest_alloc$(EXEEXT)
@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__EXEEXT_2 = ttest$(EXEEXT) \
@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ ttest_alloc$(EXEEXT)
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__EXEEXT_3 = \
......@@ -188,6 +194,11 @@ libbacktrace_noformat_la_OBJECTS = \
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta$(EXEEXT) \
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctestg_alloc$(EXEEXT) \
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta_alloc$(EXEEXT)
@NATIVE_TRUE@am_allocfail_OBJECTS = allocfail.$(OBJEXT) \
@NATIVE_TRUE@ testlib.$(OBJEXT)
allocfail_OBJECTS = $(am_allocfail_OBJECTS)
@NATIVE_TRUE@allocfail_DEPENDENCIES = \
@NATIVE_TRUE@ libbacktrace_instrumented_alloc.la
@NATIVE_TRUE@am_btest_OBJECTS = btest-btest.$(OBJEXT) \
@NATIVE_TRUE@ btest-testlib.$(OBJEXT)
btest_OBJECTS = $(am_btest_OBJECTS)
......@@ -356,8 +367,9 @@ am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libbacktrace_la_SOURCES) $(EXTRA_libbacktrace_la_SOURCES) \
$(libbacktrace_alloc_la_SOURCES) \
$(libbacktrace_noformat_la_SOURCES) $(btest_SOURCES) \
$(btest_alloc_SOURCES) $(ctesta_SOURCES) \
$(libbacktrace_instrumented_alloc_la_SOURCES) \
$(libbacktrace_noformat_la_SOURCES) $(allocfail_SOURCES) \
$(btest_SOURCES) $(btest_alloc_SOURCES) $(ctesta_SOURCES) \
$(ctesta_alloc_SOURCES) $(ctestg_SOURCES) \
$(ctestg_alloc_SOURCES) $(edtest_SOURCES) \
$(edtest_alloc_SOURCES) $(stest_SOURCES) \
......@@ -774,9 +786,10 @@ libbacktrace_la_LIBADD = \
$(ALLOC_FILE)
libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD)
TESTS = $(check_PROGRAMS) $(am__append_5)
TESTS = $(check_PROGRAMS) $(am__append_2) $(am__append_6)
@NATIVE_TRUE@check_LTLIBRARIES = libbacktrace_alloc.la \
@NATIVE_TRUE@ libbacktrace_noformat.la
@NATIVE_TRUE@ libbacktrace_noformat.la \
@NATIVE_TRUE@ libbacktrace_instrumented_alloc.la
@NATIVE_TRUE@libbacktrace_alloc_la_SOURCES = $(libbacktrace_la_SOURCES)
@NATIVE_TRUE@libbacktrace_alloc_la_LIBADD = $(BACKTRACE_FILE) $(FORMAT_FILE) read.lo alloc.lo
@NATIVE_TRUE@libbacktrace_alloc_la_DEPENDENCIES = $(libbacktrace_alloc_la_LIBADD)
......@@ -797,6 +810,15 @@ TESTS = $(check_PROGRAMS) $(am__append_5)
@NATIVE_TRUE@unittest_LDADD = libbacktrace.la
@NATIVE_TRUE@unittest_alloc_SOURCES = $(unittest_SOURCES)
@NATIVE_TRUE@unittest_alloc_LDADD = libbacktrace_alloc.la
@NATIVE_TRUE@libbacktrace_instrumented_alloc_la_SOURCES = $(libbacktrace_la_SOURCES)
@NATIVE_TRUE@libbacktrace_instrumented_alloc_la_LIBADD = $(BACKTRACE_FILE) $(FORMAT_FILE) \
@NATIVE_TRUE@ read.lo instrumented_alloc.lo
@NATIVE_TRUE@libbacktrace_instrumented_alloc_la_DEPENDENCIES = \
@NATIVE_TRUE@ $(libbacktrace_instrumented_alloc_la_LIBADD)
@NATIVE_TRUE@allocfail_SOURCES = allocfail.c testlib.c
@NATIVE_TRUE@allocfail_LDADD = libbacktrace_instrumented_alloc.la
@NATIVE_TRUE@btest_SOURCES = btest.c testlib.c
@NATIVE_TRUE@btest_CFLAGS = $(AM_CFLAGS) -g -O
@NATIVE_TRUE@btest_LDADD = libbacktrace.la
......@@ -809,9 +831,9 @@ TESTS = $(check_PROGRAMS) $(am__append_5)
@NATIVE_TRUE@stest_alloc_LDADD = libbacktrace_alloc.la
@NATIVE_TRUE@ztest_SOURCES = ztest.c testlib.c
@NATIVE_TRUE@ztest_CFLAGS = -DSRCDIR=\"$(srcdir)\"
@NATIVE_TRUE@ztest_LDADD = libbacktrace.la $(am__append_2) \
@NATIVE_TRUE@ztest_LDADD = libbacktrace.la $(am__append_3) \
@NATIVE_TRUE@ $(CLOCK_GETTIME_LINK)
@NATIVE_TRUE@ztest_alloc_LDADD = libbacktrace_alloc.la $(am__append_3) \
@NATIVE_TRUE@ztest_alloc_LDADD = libbacktrace_alloc.la $(am__append_4) \
@NATIVE_TRUE@ $(CLOCK_GETTIME_LINK)
@NATIVE_TRUE@ztest_alloc_SOURCES = $(ztest_SOURCES)
@NATIVE_TRUE@ztest_alloc_CFLAGS = $(ztest_CFLAGS)
......@@ -945,6 +967,9 @@ libbacktrace.la: $(libbacktrace_la_OBJECTS) $(libbacktrace_la_DEPENDENCIES) $(EX
libbacktrace_alloc.la: $(libbacktrace_alloc_la_OBJECTS) $(libbacktrace_alloc_la_DEPENDENCIES) $(EXTRA_libbacktrace_alloc_la_DEPENDENCIES)
$(AM_V_CCLD)$(LINK) $(am_libbacktrace_alloc_la_rpath) $(libbacktrace_alloc_la_OBJECTS) $(libbacktrace_alloc_la_LIBADD) $(LIBS)
libbacktrace_instrumented_alloc.la: $(libbacktrace_instrumented_alloc_la_OBJECTS) $(libbacktrace_instrumented_alloc_la_DEPENDENCIES) $(EXTRA_libbacktrace_instrumented_alloc_la_DEPENDENCIES)
$(AM_V_CCLD)$(LINK) $(am_libbacktrace_instrumented_alloc_la_rpath) $(libbacktrace_instrumented_alloc_la_OBJECTS) $(libbacktrace_instrumented_alloc_la_LIBADD) $(LIBS)
libbacktrace_noformat.la: $(libbacktrace_noformat_la_OBJECTS) $(libbacktrace_noformat_la_DEPENDENCIES) $(EXTRA_libbacktrace_noformat_la_DEPENDENCIES)
$(AM_V_CCLD)$(LINK) $(am_libbacktrace_noformat_la_rpath) $(libbacktrace_noformat_la_OBJECTS) $(libbacktrace_noformat_la_LIBADD) $(LIBS)
......@@ -957,6 +982,10 @@ clean-checkPROGRAMS:
echo " rm -f" $$list; \
rm -f $$list
allocfail$(EXEEXT): $(allocfail_OBJECTS) $(allocfail_DEPENDENCIES) $(EXTRA_allocfail_DEPENDENCIES)
@rm -f allocfail$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(allocfail_OBJECTS) $(allocfail_LDADD) $(LIBS)
btest$(EXEEXT): $(btest_OBJECTS) $(btest_DEPENDENCIES) $(EXTRA_btest_DEPENDENCIES)
@rm -f btest$(EXEEXT)
$(AM_V_CCLD)$(btest_LINK) $(btest_OBJECTS) $(btest_LDADD) $(LIBS)
......@@ -1434,6 +1463,13 @@ unittest_alloc.log: unittest_alloc$(EXEEXT)
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
allocfail.log: allocfail$(EXEEXT)
@p='allocfail$(EXEEXT)'; \
b='allocfail'; \
$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
btest.log: btest$(EXEEXT)
@p='btest$(EXEEXT)'; \
b='btest'; \
......@@ -1532,6 +1568,13 @@ ctesta_alloc.log: ctesta_alloc$(EXEEXT)
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
allocfail.sh.log: allocfail.sh
@p='allocfail.sh'; \
b='allocfail.sh'; \
$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
dtest.log: dtest
@p='dtest'; \
b='dtest'; \
......@@ -1695,6 +1738,10 @@ uninstall-am:
@NATIVE_TRUE@ $(srcdir)/xcoff.c \
@NATIVE_TRUE@ > $@
@NATIVE_TRUE@instrumented_alloc.lo: alloc.c
@NATIVE_TRUE@allocfail.sh: allocfail
@NATIVE_TRUE@edtest2_build.c: gen_edtest2_build; @true
@NATIVE_TRUE@gen_edtest2_build: $(srcdir)/edtest2.c
@NATIVE_TRUE@ cat $(srcdir)/edtest2.c > tmp-edtest2_build.c
......
/* allocfail.c -- Test for libbacktrace library
Copyright (C) 2018 Free Software Foundation, Inc.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
(1) Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
(2) Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "filenames.h"
#include "backtrace.h"
#include "backtrace-supported.h"
#include "testlib.h"
extern uint64_t get_nr_allocs (void);
extern void set_fail_at_alloc (uint64_t);
extern int at_fail_alloc_p (void);
static int test1 (void) __attribute__ ((noinline, unused));
static int f2 (int) __attribute__ ((noinline));
static int f3 (int, int) __attribute__ ((noinline));
static unsigned callback_errors = 0;
static void
error_callback_full (void *vdata ATTRIBUTE_UNUSED,
const char *msg ATTRIBUTE_UNUSED,
int errnum ATTRIBUTE_UNUSED)
{
if (at_fail_alloc_p ())
{
set_fail_at_alloc (0);
return;
}
callback_errors++;
}
static int
callback_full (void *vdata ATTRIBUTE_UNUSED, uintptr_t pc ATTRIBUTE_UNUSED,
const char *filename ATTRIBUTE_UNUSED,
int lineno ATTRIBUTE_UNUSED,
const char *function ATTRIBUTE_UNUSED)
{
return 0;
}
static int
test1 (void)
{
return f2 (__LINE__) + 1;
}
static int
f2 (int f1line)
{
return f3 (f1line, __LINE__) + 2;
}
static int
f3 (int f1line ATTRIBUTE_UNUSED, int f2line ATTRIBUTE_UNUSED)
{
int i;
i = backtrace_full (state, 0, callback_full, error_callback_full, NULL);
if (i != 0)
{
fprintf (stderr, "test1: unexpected return value %d\n", i);
++failures;
}
if (callback_errors)
++failures;
return failures;
}
/* Run all the tests. */
int
main (int argc, char **argv)
{
uint64_t fail_at = 0;
if (argc == 2)
{
fail_at = atoi (argv[1]);
set_fail_at_alloc (fail_at);
}
state = backtrace_create_state (argv[0], BACKTRACE_SUPPORTS_THREADS,
error_callback_full, NULL);
if (state == NULL)
exit (failures ? EXIT_FAILURE : EXIT_SUCCESS);
#if BACKTRACE_SUPPORTED
test1 ();
#endif
if (argc == 1)
fprintf (stderr, "%lu\n", get_nr_allocs ());
exit (failures ? EXIT_FAILURE : EXIT_SUCCESS);
}
#!/bin/sh
# allocfail.sh -- Test for libbacktrace library.
# Copyright (C) 2018 Free Software Foundation, Inc.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# (1) Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# (2) Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# (3) The name of the author may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
set -e
set -o pipefail
if [ ! -f ./allocfail ]; then
# Hard failure.
exit 99
fi
allocs=$(./allocfail 2>&1)
if [ "$allocs" = "" ]; then
# Hard failure.
exit 99
fi
# This generates the following output:
# ...
# $ allocfail.sh
# allocs: 80495
# Status changed to 0 at 1
# Status changed to 1 at 3
# Status changed to 0 at 11
# Status changed to 1 at 12
# Status changed to 0 at 845
# ...
#
# We have status 0 for an allocation failure at:
# - 1 because backtrace_create_state handles failure robustly
# - 2 because the fail switches backtrace_full to !can_alloc mode.
# - 11 because failure of elf_open_debugfile_by_buildid does not generate an
# error callback beyond the one for the allocation failure itself.
echo "allocs: $allocs"
step=1
i=1
passes=0
prev_status=-1
while [ $i -le $allocs ]; do
if ./allocfail $i >/dev/null 2>&1; status=$?; then
true
fi
if [ $status -gt 1 ]; then
echo "Unallowed fail found: $i"
# Failure.
exit 1
fi
# The test-case would run too long if we would excercise all allocs.
# So, run with step 1 initially, and increase the step once we have 10
# subsequent passes, and drop back to step 1 once we encounter another
# failure. This takes ~2.6 seconds on an i7-6600U CPU @ 2.60GHz.
if [ $status -eq 0 ]; then
passes=$(($passes + 1))
if [ $passes -ge 10 ]; then
step=$((step * 10))
passes=0
fi
elif [ $status -eq 1 ]; then
passes=0
step=1
fi
if [ $status -ne $prev_status ]; then
echo "Status changed to $status at $i"
fi
prev_status=$status
i=$(($i + $step))
done
# Success.
exit 0
/* instrumented_alloc.c -- Memory allocation instrumented to fail when
requested, for testing purposes.
Copyright (C) 2018 Free Software Foundation, Inc.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
(1) Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
(2) Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */
/* Include all the header files of alloc here, to make sure they're not
processed when including alloc.c below, such that the redefinitions of malloc
and realloc are only effective in alloc.c itself. This does not work for
config.h, because it's not wrapped in "#ifndef CONFIG_H\n#define CONFIG_H"
and "#endif" but that does not seem to be harmful. */
#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <inttypes.h>
#include "backtrace.h"
#include "internal.h"
extern void *instrumented_malloc (size_t size);
extern void *instrumented_realloc (void *ptr, size_t size);
#define malloc instrumented_malloc
#define realloc instrumented_realloc
#include "alloc.c"
#undef malloc
#undef realloc
static uint64_t nr_allocs = 0;
static uint64_t fail_at_alloc = 0;
extern int at_fail_alloc_p (void);
extern uint64_t get_nr_allocs (void);
extern void set_fail_at_alloc (uint64_t);
void *
instrumented_malloc (size_t size)
{
void *res;
if (at_fail_alloc_p ())
return NULL;
res = malloc (size);
if (res != NULL)
nr_allocs++;
return res;
}
void *
instrumented_realloc (void *ptr, size_t size)
{
void *res;
if (size != 0)
{
if (at_fail_alloc_p ())
return NULL;
}
res = realloc (ptr, size);
if (res != NULL)
nr_allocs++;
return res;
}
int
at_fail_alloc_p (void)
{
return fail_at_alloc == nr_allocs + 1;
}
uint64_t
get_nr_allocs (void)
{
return nr_allocs;
}
void
set_fail_at_alloc (uint64_t nr)
{
fail_at_alloc = nr;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment