gmon: Add test for basic mcount/gprof functionality

This commit is contained in:
Florian Weimer 2017-08-15 15:49:40 +02:00
parent ee72219a49
commit 6014c65de2
8 changed files with 149 additions and 2 deletions

View File

@ -1,3 +1,18 @@
2017-08-15 Florian Weimer <fweimer@redhat.com>
* gmon/Makefile (tests): Add tst-gmon.
(CFLAGS-tst-gmon.c, LDFLAGS-tst-gmon, CRT-tst-gmon, tst-gmon-ENV):
Set.
(tests-special): Add tst-gmon-prof.out.
(tst-gmon.out): Depend on clean-tst-gmon-data.
(clean-tst-gmon-data, tst-gmon-gprof.out): New targets.
* gmon/tst-gmon.c, gmon/tst-gmon-gprof.sh: New files.
* Makeconfig (+link-before-libc): Add CRT-* hook to override the
startup object.
* aclocal.m4 (GPROF): Set and substitute.
* config.amke.in (GPROF): Set.
* configure: Regenerate.
2017-08-15 Gustavo Romero <gromero@linux.vnet.ibm.com>
* elf/elf.h A (NT_PPC_TAR): New macro.

View File

@ -465,7 +465,7 @@ else # not build-pie-default
+link-before-libc = $(CC) -nostdlib -nostartfiles -o $@ \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
$(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
$(addprefix $(csu-objpfx),$(start-installed-name)) \
$(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-installed-name)) \
$(+preinit) $(+prector) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\

2
aclocal.m4 vendored
View File

@ -121,6 +121,8 @@ OBJDUMP=`$CC -print-prog-name=objdump`
AC_SUBST(OBJDUMP)
OBJCOPY=`$CC -print-prog-name=objcopy`
AC_SUBST(OBJCOPY)
GPROF=`$CC -print-prog-name=gprof`
AC_SUBST(GPROF)
# Determine whether we are using GNU binutils.
AC_CACHE_CHECK(whether $AS is GNU as, libc_cv_prog_as_gnu,

View File

@ -120,6 +120,7 @@ BISON = @BISON@
AUTOCONF = @AUTOCONF@
OBJDUMP = @OBJDUMP@
OBJCOPY = @OBJCOPY@
GPROF = @GPROF@
READELF = @READELF@
# Installation tools.

3
configure vendored
View File

@ -651,6 +651,7 @@ MSGFMT
MAKE
LD
AS
GPROF
OBJCOPY
OBJDUMP
AR
@ -4572,6 +4573,8 @@ OBJDUMP=`$CC -print-prog-name=objdump`
OBJCOPY=`$CC -print-prog-name=objcopy`
GPROF=`$CC -print-prog-name=gprof`
# Determine whether we are using GNU binutils.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $AS is GNU as" >&5

View File

@ -27,7 +27,7 @@ routines := gmon mcount profil sprofil bb_init_func bb_exit_func prof-freq
elide-routines.os = bb_init_func bb_exit_func
tests = tst-sprofil
tests = tst-sprofil tst-gmon
ifeq ($(build-profile),yes)
tests += tst-profile-static
tests-static += tst-profile-static
@ -38,6 +38,12 @@ endif
# The mcount code won't work without a frame pointer.
CFLAGS-mcount.c := -fno-omit-frame-pointer
CFLAGS-tst-gmon.c := -pg
LDFLAGS-tst-gmon := $(no-pie-ldflag)
CRT-tst-gmon := $(csu-objpfx)gcrt1.o
tst-gmon-ENV := GMON_OUT_PREFIX=$(objpfx)tst-gmon.data
tests-special += $(objpfx)tst-gmon-gprof.out
include ../Rules
# We cannot compile mcount.c with -pg because that would
@ -53,3 +59,13 @@ endif
$(noprof:%=$(objpfx)%.op): %.op: %.o
rm -f $@
ln $< $@
# GMON_OUTPUT_PREFIX only sets the output prefix. The actual file
# name contains the PID as well.
$(objpfx)tst-gmon.out: clean-tst-gmon-data
clean-tst-gmon-data:
rm -f $(objpfx)tst-gmon.data.*
$(objpfx)tst-gmon-gprof.out: tst-gmon-gprof.sh $(objpfx)tst-gmon.out
$(SHELL) $< $(GPROF) $(objpfx)tst-gmon $(objpfx)tst-gmon.data.* > $@; \
$(evaluate-test)

60
gmon/tst-gmon-gprof.sh Normal file
View File

@ -0,0 +1,60 @@
#!/bin/sh
# Check the output of gprof against a carfully crafted binary.
# Copyright (C) 2017 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
# <http://www.gnu.org/licenses/>.
LC_ALL=C
export LC_ALL
set -e
exec 2>&1
GPROF="$1"
program="$2"
data="$3"
actual=$(mktemp)
expected=$(mktemp)
expected_dot=$(mktemp)
cleanup () {
rm -f "$actual"
rm -f "$expected"
rm -f "$expected_dot"
}
trap cleanup 0
cat > "$expected" <<EOF
f1 2000
f2 1000
EOF
# Special version for powerpc with function descriptors.
cat > "$expected_dot" <<EOF
.f1 2000
.f2 1000
EOF
"$GPROF" -C "$program" "$data" \
| awk -F '[(): ]' '/executions/{print $5, $8}' \
| sort > "$actual"
if cmp -s "$actual" "$expected_dot" \
|| diff -u --label expected "$expected" --label actual "$actual" ; then
echo "PASS"
else
echo "FAIL"
exit 1
fi

50
gmon/tst-gmon.c Normal file
View File

@ -0,0 +1,50 @@
/* Test program for profiling information collection (_mcount/gprof).
Copyright (C) 2017 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
<http://www.gnu.org/licenses/>. */
/* This program does not use the test harness because we want tight
control over the call graph. */
__attribute__ ((noinline, noclone, weak)) void
f1 (void)
{
}
__attribute__ ((noinline, noclone, weak)) void
f2 (void)
{
f1 ();
/* Prevent tail call. */
asm volatile ("");
}
__attribute__ ((noinline, noclone, weak)) void
f3 (int count)
{
for (int i = 0; i < count; ++i)
{
f1 ();
f2 ();
}
}
int
main (void)
{
f3 (1000);
return 0;
}