Add a test for profiling static executable
Commit Message
The function, main, is added to profiling output of static executable
which must link against gcrt1.o.
Tested on x86-64. OK for master?
H.J.
---
* Makeconfig (+link-static-before-libc): Use the first of
$(CRT-$(@F)) and $(csu-objpfx)$(static-start-installed-name).
* gmon/Makefile (tests): Add tst-gmon-static.
(tests-static): Likewise.
(CFLAGS-tst-gmon-static.c): New.
(CRT-tst-gmon-static): Likewise.
(DEFAULT-LDFLAGS-tst-gmon-static): Likewise.
(tst-gmon-static-ENV): Likewise.
(tests-special): Likewise.
($(objpfx)tst-gmon-static.out): Likewise.
(clean-tst-gmon-static-data): Likewise.
($(objpfx)tst-gmon-static-gprof.out): Likewise.
* gmon/tst-gmon-static-gprof.sh: New file.
* gmon/tst-gmon-static.c: Likewise.
---
Makeconfig | 2 +-
gmon/Makefile | 21 +++++++++++++++
gmon/tst-gmon-static-gprof.sh | 62 +++++++++++++++++++++++++++++++++++++++++++
gmon/tst-gmon-static.c | 1 +
4 files changed, 85 insertions(+), 1 deletion(-)
create mode 100644 gmon/tst-gmon-static-gprof.sh
create mode 100644 gmon/tst-gmon-static.c
Comments
On Thu, Oct 12, 2017 at 1:07 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> The function, main, is added to profiling output of static executable
> which must link against gcrt1.o.
>
> Tested on x86-64. OK for master?
>
> H.J.
> ---
> * Makeconfig (+link-static-before-libc): Use the first of
> $(CRT-$(@F)) and $(csu-objpfx)$(static-start-installed-name).
> * gmon/Makefile (tests): Add tst-gmon-static.
> (tests-static): Likewise.
> (CFLAGS-tst-gmon-static.c): New.
> (CRT-tst-gmon-static): Likewise.
> (DEFAULT-LDFLAGS-tst-gmon-static): Likewise.
> (tst-gmon-static-ENV): Likewise.
> (tests-special): Likewise.
> ($(objpfx)tst-gmon-static.out): Likewise.
> (clean-tst-gmon-static-data): Likewise.
> ($(objpfx)tst-gmon-static-gprof.out): Likewise.
> * gmon/tst-gmon-static-gprof.sh: New file.
> * gmon/tst-gmon-static.c: Likewise.
> ---
> Makeconfig | 2 +-
> gmon/Makefile | 21 +++++++++++++++
> gmon/tst-gmon-static-gprof.sh | 62 +++++++++++++++++++++++++++++++++++++++++++
> gmon/tst-gmon-static.c | 1 +
> 4 files changed, 85 insertions(+), 1 deletion(-)
> create mode 100644 gmon/tst-gmon-static-gprof.sh
> create mode 100644 gmon/tst-gmon-static.c
>
> diff --git a/Makeconfig b/Makeconfig
> index 5ff6f2e29a..1346109ac0 100644
> --- a/Makeconfig
> +++ b/Makeconfig
> @@ -422,7 +422,7 @@ ifndef +link-static
> +link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \
> $(DEFAULT-LDFLAGS-$(@F)) \
> $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
> - $(addprefix $(csu-objpfx),$(static-start-installed-name)) \
> + $(firstword $(CRT-$(@F)) $(csu-objpfx)$(static-start-installed-name)) \
> $(+preinit) $(+prectorT) \
> $(filter-out $(addprefix $(csu-objpfx),start.o \
> $(start-installed-name))\
> diff --git a/gmon/Makefile b/gmon/Makefile
> index 2cd077dece..89ab3fc7da 100644
> --- a/gmon/Makefile
> +++ b/gmon/Makefile
> @@ -33,6 +33,9 @@ tests-static += tst-profile-static
> LDFLAGS-tst-profile-static = -profile
> endif
>
> +tests += tst-gmon-static
> +tests-static += tst-gmon-static
> +
> ifeq (yesyes,$(have-fpie)$(build-shared))
> tests += tst-gmon-pie
> tests-pie += tst-gmon-pie
> @@ -49,6 +52,14 @@ ifeq ($(run-built-tests),yes)
> tests-special += $(objpfx)tst-gmon-gprof.out
> endif
>
> +CFLAGS-tst-gmon-static.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg
> +CRT-tst-gmon-static := $(csu-objpfx)gcrt1.o
> +DEFAULT-LDFLAGS-tst-gmon-static = $(no-pie-ldflag)
> +tst-gmon-static-ENV := GMON_OUT_PREFIX=$(objpfx)tst-gmon-static.data
> +ifeq ($(run-built-tests),yes)
> +tests-special += $(objpfx)tst-gmon-static-gprof.out
> +endif
> +
> CFLAGS-tst-gmon-pie.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg
> CRT-tst-gmon-pie := $(csu-objpfx)gcrt1.o
> tst-gmon-pie-ENV := GMON_OUT_PREFIX=$(objpfx)tst-gmon-pie.data
> @@ -83,6 +94,16 @@ $(objpfx)tst-gmon-gprof.out: tst-gmon-gprof.sh $(objpfx)tst-gmon.out
> $(SHELL) $< $(GPROF) $(objpfx)tst-gmon $(objpfx)tst-gmon.data.* > $@; \
> $(evaluate-test)
>
> +$(objpfx)tst-gmon-static.out: clean-tst-gmon-static-data
> +clean-tst-gmon-static-data:
> + rm -f $(objpfx)tst-gmon-static.data.*
> +
> +$(objpfx)tst-gmon-static-gprof.out: tst-gmon-static-gprof.sh \
> + $(objpfx)tst-gmon-static.out
> + $(SHELL) $< $(GPROF) $(objpfx)tst-gmon-static \
> + $(objpfx)tst-gmon-static.data.* > $@; \
> + $(evaluate-test)
> +
> $(objpfx)tst-gmon-pie.out: clean-tst-gmon-pie-data
> clean-tst-gmon-pie-data:
> rm -f $(objpfx)tst-gmon-pie.data.*
> diff --git a/gmon/tst-gmon-static-gprof.sh b/gmon/tst-gmon-static-gprof.sh
> new file mode 100644
> index 0000000000..55ac8aa69f
> --- /dev/null
> +++ b/gmon/tst-gmon-static-gprof.sh
> @@ -0,0 +1,62 @@
> +#!/bin/sh
> +# Check the output of gprof against a carfully crafted static 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
> +main 1
> +EOF
> +
> +# Special version for powerpc with function descriptors.
> +cat > "$expected_dot" <<EOF
> +.f1 2000
> +.f2 1000
> +.main 1
> +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
> diff --git a/gmon/tst-gmon-static.c b/gmon/tst-gmon-static.c
> new file mode 100644
> index 0000000000..1eef2583b6
> --- /dev/null
> +++ b/gmon/tst-gmon-static.c
> @@ -0,0 +1 @@
> +#include "tst-gmon.c"
> --
> 2.13.6
>
I am checking it in.
@@ -422,7 +422,7 @@ ifndef +link-static
+link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \
$(DEFAULT-LDFLAGS-$(@F)) \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
- $(addprefix $(csu-objpfx),$(static-start-installed-name)) \
+ $(firstword $(CRT-$(@F)) $(csu-objpfx)$(static-start-installed-name)) \
$(+preinit) $(+prectorT) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
@@ -33,6 +33,9 @@ tests-static += tst-profile-static
LDFLAGS-tst-profile-static = -profile
endif
+tests += tst-gmon-static
+tests-static += tst-gmon-static
+
ifeq (yesyes,$(have-fpie)$(build-shared))
tests += tst-gmon-pie
tests-pie += tst-gmon-pie
@@ -49,6 +52,14 @@ ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-gmon-gprof.out
endif
+CFLAGS-tst-gmon-static.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg
+CRT-tst-gmon-static := $(csu-objpfx)gcrt1.o
+DEFAULT-LDFLAGS-tst-gmon-static = $(no-pie-ldflag)
+tst-gmon-static-ENV := GMON_OUT_PREFIX=$(objpfx)tst-gmon-static.data
+ifeq ($(run-built-tests),yes)
+tests-special += $(objpfx)tst-gmon-static-gprof.out
+endif
+
CFLAGS-tst-gmon-pie.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg
CRT-tst-gmon-pie := $(csu-objpfx)gcrt1.o
tst-gmon-pie-ENV := GMON_OUT_PREFIX=$(objpfx)tst-gmon-pie.data
@@ -83,6 +94,16 @@ $(objpfx)tst-gmon-gprof.out: tst-gmon-gprof.sh $(objpfx)tst-gmon.out
$(SHELL) $< $(GPROF) $(objpfx)tst-gmon $(objpfx)tst-gmon.data.* > $@; \
$(evaluate-test)
+$(objpfx)tst-gmon-static.out: clean-tst-gmon-static-data
+clean-tst-gmon-static-data:
+ rm -f $(objpfx)tst-gmon-static.data.*
+
+$(objpfx)tst-gmon-static-gprof.out: tst-gmon-static-gprof.sh \
+ $(objpfx)tst-gmon-static.out
+ $(SHELL) $< $(GPROF) $(objpfx)tst-gmon-static \
+ $(objpfx)tst-gmon-static.data.* > $@; \
+ $(evaluate-test)
+
$(objpfx)tst-gmon-pie.out: clean-tst-gmon-pie-data
clean-tst-gmon-pie-data:
rm -f $(objpfx)tst-gmon-pie.data.*
new file mode 100644
@@ -0,0 +1,62 @@
+#!/bin/sh
+# Check the output of gprof against a carfully crafted static 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
+main 1
+EOF
+
+# Special version for powerpc with function descriptors.
+cat > "$expected_dot" <<EOF
+.f1 2000
+.f2 1000
+.main 1
+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
new file mode 100644
@@ -0,0 +1 @@
+#include "tst-gmon.c"