mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-16 23:31:05 +08:00
[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
This commit is contained in:
parent
bf4eca2e56
commit
d665cd9b13
@ -1,3 +1,13 @@
|
||||
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
|
||||
|
136
libbacktrace/allocfail.c
Normal file
136
libbacktrace/allocfail.c
Normal file
@ -0,0 +1,136 @@
|
||||
/* 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);
|
||||
}
|
105
libbacktrace/allocfail.sh
Executable file
105
libbacktrace/allocfail.sh
Executable file
@ -0,0 +1,105 @@
|
||||
#!/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
|
114
libbacktrace/instrumented_alloc.c
Normal file
114
libbacktrace/instrumented_alloc.c
Normal file
@ -0,0 +1,114 @@
|
||||
/* 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user