[PATCH v2 2/4] tests/: add test suite for stackprof
Aaron Merey
amerey@redhat.com
Tue Jul 14 23:44:58 GMT 2026
Hi Serhei,
On Wed, Jun 24, 2026 at 5:07 PM Serhei Makarov <serhei@serhei.io> wrote:
>
> Together with the stackprof tool we add some test cases to exercise
> it, and the underlying libdwfl_stacktrace functionality as well.
>
> * tests/stackprof-subr.sh: Common subroutines for checking
> perf_events availability and verifying gmon.*.out files.
> * tests/run-stackprof-system.sh: New file.
> * tests/run-stackprof-system-gprof.sh: New file.
> * tests/run-stackprof-user.sh: New file.
> * tests/run-stackprof-user-gprof.sh: New file.
> * tests/Makefile.am (TESTS): add the new testcases.
>
> Co-authored-by: <fche@redhat.com>
> Signed-off-by: <serhei@serhei.io>
> ---
> tests/Makefile.am | 14 +++++-
> tests/run-stackprof-system-gprof.sh | 49 +++++++++++++++++++++
> tests/run-stackprof-system.sh | 45 ++++++++++++++++++++
> tests/run-stackprof-user-gprof.sh | 41 ++++++++++++++++++
> tests/run-stackprof-user.sh | 57 +++++++++++++++++++++++++
> tests/stackprof-subr.sh | 66 +++++++++++++++++++++++++++++
> 6 files changed, 270 insertions(+), 2 deletions(-)
> create mode 100755 tests/run-stackprof-system-gprof.sh
> create mode 100755 tests/run-stackprof-system.sh
> create mode 100755 tests/run-stackprof-user-gprof.sh
> create mode 100755 tests/run-stackprof-user.sh
> create mode 100644 tests/stackprof-subr.sh
>
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index 8ae7d126..f098d31f 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -1,6 +1,6 @@
> ## Process this file with automake to create Makefile.in
> ##
> -## Copyright (C) 1996-2019 Red Hat, Inc.
> +## Copyright (C) 1996-2026 Red Hat, Inc.
> ## This file is part of elfutils.
> ##
> ## This file is free software; you can redistribute it and/or modify
> @@ -313,7 +313,7 @@ TESTS += run-debuginfod-ima-verification.sh
> endif
> endif
>
> -if HAVE_CXX11
> +if HAVE_CXX20
> check_PROGRAMS += funcretval_test++11
> funcretval_test__11_SOURCES = funcretval_test++11.cxx
> TESTS += run-funcretval++11.sh
> @@ -323,6 +323,14 @@ check_PROGRAMS += funcretval_test_struct
> funcretval_test_struct_SOURCES = funcretval_test_struct.c
> TESTS += run-funcretval-struct-native.sh
>
> +if ENABLE_STACKPROF
> +TESTS += run-stackprof-user.sh run-stackprof-user-gprof.sh
> +TESTS += run-stackprof-system.sh run-stackprof-system-gprof.sh
> +endif
> +if HAVE_LIBPFM
> +export HAVE_LIBPFM = 1
> +endif
> +
> EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
> run-ar-N.sh \
> run-show-die-info.sh run-get-files.sh run-get-lines.sh \
> @@ -717,6 +725,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
> testfile-sysroot.tar.bz2 run-sysroot.sh \
> run-test-manyfuncs.sh manyfuncs.c \
> run-debuginfod-seekable.sh thread-safety-subr.sh \
> + run-stackprof-user.sh run-stackprof-user-gprof.sh \
> + run-stackprof-system.sh run-stackprof-system-gprof.sh \
stackprof-subr.sh should be included in EXTRA_DIST.
> run-eu-search-cfi.sh run-eu-search-macros.sh \
> run-eu-search-lines.sh run-eu-search-die.sh
>
> diff --git a/tests/run-stackprof-system-gprof.sh b/tests/run-stackprof-system-gprof.sh
> new file mode 100755
> index 00000000..c281167c
> --- /dev/null
> +++ b/tests/run-stackprof-system-gprof.sh
> @@ -0,0 +1,49 @@
> +#!/usr/bin/env bash
> +#
> +# Copyright (C) 2026 Red Hat, Inc.
> +# This file is part of elfutils.
> +#
> +# This file is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# elfutils 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 General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +. $srcdir/stackprof-subr.sh
> +
> +set -x
> +unset VALGRIND_CMD
> +
> +# prerequisites
> +type timeout 2>/dev/null || (echo "no timeout installed"; exit 77)
> +type gprof 2>/dev/null || (echo "no gprof installed"; exit 77)
> +check_perf_event_open || (echo "perf_event_open fails (check kernel.perf_event_paranoid + kernel config)"; exit 77)
> +expr `whoami` = "root" || (echo "not running as root"; exit 77)
> +
> +tempfiles test.out
> +
> +# run systemwide scan, no gprof output
> +testrun timeout -p --kill-after=5 10 ${abs_top_builddir}/src/stackprof -v 2>&1 | tee test.out
> +grep "^perf_event_attr configuration" test.out
> +grep "Starting stack profile collection systemwide" test.out || (grep "ERROR: Unsupported architecture" test.out && echo "unsupported arch" && exit 77)
> +grep -E "^[0-9]+ " test.out # -- pid / sample counts entries
> +
> +# run systemwide scan again, with gprof output
> +# reduce verbosity, bump post-processing timeout compared to the first run
> +testrun timeout -p --kill-after=10 10 ${abs_top_builddir}/src/stackprof -g 2>&1 | tee test.out
> +tempfiles gmon.*
> +grep "^perf_event_attr configuration" test.out
> +grep "Starting stack profile collection systemwide" test.out
> +grep -E "^buildid [0-9a-f]+" test.out
> +
> +stackprof_debuginfod_setup
> +stackprof_check_gmon_out
> +
> +exit 0
> diff --git a/tests/run-stackprof-system.sh b/tests/run-stackprof-system.sh
> new file mode 100755
> index 00000000..cb796a71
> --- /dev/null
> +++ b/tests/run-stackprof-system.sh
> @@ -0,0 +1,45 @@
> +#!/usr/bin/env bash
> +#
> +# Copyright (C) 2026 Red Hat, Inc.
> +# This file is part of elfutils.
> +#
> +# This file is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# elfutils 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 General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +. $srcdir/stackprof-subr.sh
> +
> +set -x
> +unset VALGRIND_CMD
> +
> +# prerequisites
> +type timeout 2>/dev/null || (echo "no timeout installed"; exit 77)
> +check_perf_event_open || (echo "perf_event_open fails (check kernel.perf_event_paranoid + kernel config)"; exit 77)
> +expr `whoami` = "root" || (echo "not running as root"; exit 77)
> +
> +tempfiles test.out
> +
> +# run systemwide scan, no gprof output
> +testrun timeout -p --kill-after=5 10 ${abs_top_builddir}/src/stackprof -v 2>&1 | tee test.out
> +grep "^perf_event_attr configuration" test.out
> +grep "Starting stack profile collection systemwide" test.out || (grep "ERROR: Unsupported architecture" test.out && echo "unsupported arch" && exit 77)
> +grep -E "^[0-9]+ " test.out # -- pid / sample counts entries
> +
> +# run systemwide scan again, with gprof output
> +# reduce verbosity, bump post-processing timeout compared to the first run
> +testrun timeout -p --kill-after=10 15 ${abs_top_builddir}/src/stackprof -g 2>&1 | tee test.out
> +tempfiles gmon.*
> +grep "^perf_event_attr configuration" test.out
> +grep "Starting stack profile collection systemwide" test.out
> +grep -E "^buildid [0-9a-f]+" test.out
> +
> +exit 0
> diff --git a/tests/run-stackprof-user-gprof.sh b/tests/run-stackprof-user-gprof.sh
> new file mode 100755
> index 00000000..9360f8b8
> --- /dev/null
> +++ b/tests/run-stackprof-user-gprof.sh
> @@ -0,0 +1,41 @@
> +#!/usr/bin/env bash
> +#
> +# Copyright (C) 2026 Red Hat, Inc.
> +# This file is part of elfutils.
> +#
> +# This file is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# elfutils 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 General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +. $srcdir/stackprof-subr.sh
> +
> +set -x
> +unset VALGRIND_CMD
> +
> +# prerequisites
> +type timeout 2>/dev/null || (echo "no timeout installed"; exit 77)
> +type gprof 2>/dev/null || (echo "no gprof installed"; exit 77)
> +check_perf_event_open || (echo "perf_event_open fails (check kernel.perf_event_paranoid + kernel config)"; exit 77)
> +
> +tempfiles test.out
> +
> +# run on single executable, with gprof output
> +testrun ${abs_top_builddir}/src/stackprof -v -g -- timeout 2 /bin/sh -c "while true; do true; done" 2>&1 | tee test.out
> +tempfiles gmon.*
> +grep "^perf_event_attr configuration" test.out
> +grep "Starting stack profile collection pid" test.out || (grep "ERROR: Unsupported architecture" test.out && echo "unsupported arch" && exit 77)
> +grep -E "^buildid [0-9a-f]+" test.out
> +
> +stackprof_debuginfod_setup
> +stackprof_check_gmon_out
> +
> +exit 0
> diff --git a/tests/run-stackprof-user.sh b/tests/run-stackprof-user.sh
> new file mode 100755
> index 00000000..722b7b02
> --- /dev/null
> +++ b/tests/run-stackprof-user.sh
> @@ -0,0 +1,57 @@
> +#!/usr/bin/env bash
> +#
> +# Copyright (C) 2026 Red Hat, Inc.
> +# This file is part of elfutils.
> +#
> +# This file is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# elfutils 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 General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +. $srcdir/stackprof-subr.sh
> +
> +set -x
> +unset VALGRIND_CMD
> +
> +# prerequisites
> +type timeout 2>/dev/null || (echo "no timeout installed"; exit 77)
> +check_perf_event_open || (echo "perf_event_open fails (check kernel.perf_event_paranoid + kernel config)"; exit 77)
> +
> +tempfiles test.out
> +
> +# run on single executable, no gprof output
> +testrun ${abs_top_builddir}/src/stackprof -v -- timeout 2 /bin/sh -c "while true; do true; done" 2>&1 | tee test.out
> +grep "^perf_event_attr configuration" test.out
> +grep "Starting stack profile collection pid" test.out || (grep "ERROR: Unsupported architecture" test.out && echo "unsupported arch" && exit 77)
> +grep -E "^[0-9]+ sh --" test.out # -- pid / sample counts entries
> +
> +# run on single executable again, with gprof output
> +testrun ${abs_top_builddir}/src/stackprof -g -- timeout 2 /bin/sh -c "while true; do true; done" 2>&1 | tee test.out
> +tempfiles gmon.*
> +grep "^perf_event_attr configuration type=1 config=0 sample_freq=" test.out
> +grep "Starting stack profile collection pid" test.out
> +grep -E "^buildid [0-9a-f]+" test.out
> +rm -f gmon.*
> +
> +# test libpfm event listing
> +if [ "x$HAVE_LIBPFM" = "x1" ]; then
> + testrun ${abs_top_builddir}/src/stackprof --event-list 2>&1 | tee test.out
> + grep "^perf::BRANCHES" test.out
> +
> + # run on single executable, with libpfm
> + testrun ${abs_top_builddir}/src/stackprof -v -e perf::BRANCHES:freq=4000 -g -- timeout 2 /bin/sh -c "while true; do true; done" 2>&1 | tee test out
This should be test.out instead of test out.
> + tempfiles gmon.*
> + grep "^perf_event_attr configuration type=0 config=4 sample_freq=4000" test.out
> + grep "Starting stack profile collection pid" test.out
> + grep -E "^buildid [0-9a-f]+" test.out
> +fi
> +
> +exit 0
> diff --git a/tests/stackprof-subr.sh b/tests/stackprof-subr.sh
> new file mode 100644
> index 00000000..729053dd
> --- /dev/null
> +++ b/tests/stackprof-subr.sh
> @@ -0,0 +1,66 @@
> +# Copyright (C) 2021 Red Hat, Inc.
> +# This file is part of elfutils.
> +#
> +# This file is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# elfutils 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 General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +# sourced from run-stackprof-*.sh tests (must be bash scripts)
> +
> +. $srcdir/test-subr.sh
> +
> +check_perf_event_open() {
> + tempfiles perf-test.out
> + if ! testrun timeout 2 ${abs_top_builddir}/src/stackprof -v -- /bin/true > perf-test.out 2>&1; then
> + if grep -q "perf_event_open.*failed\|Operation not permitted\|Permission denied"; then
This grep command should read from perf-test.out.
Aaron
> + return 77
> + fi
> + fi
> + return 0
> +}
> +
> +stackprof_debuginfod_setup() {
> + # uncomment to test with networked debuginfod
> + #export DEBUGINFOD_URLS=https://debuginfod.elfutils.org/
> + return 0
> +}
> +
> +stackprof_check_gmon_out() {
> + for f in gmon.*.out
> + do
> + exe="`basename "$f" .out`.exe"
> + if [ ! -f "$exe" ]; then
> + buildid=`echo "$f" | cut -f2 -d.`
> + if ! testrun ${abs_top_builddir}/debuginfod/debuginfod-find -v executable $buildid; then
> + echo "$exe not found, skipping"
> + continue
> + fi
> + ln -s "`${abs_top_builddir}/debuginfod/debuginfod-find executable $buildid`" "$exe"
> + fi
> + tempfiles "$exe" gprof_output.txt
> + exe_info="$exe (`readlink $exe`)"
> + # try a plain gprof run on the executable
> + if gprof "$exe" "$f" > gprof_output.txt 2>&1; then
> + echo "$exe_info"
> + cat gprof_output.txt
> + continue
> + fi
> + # else fall back to debuginfod
> + if ! testrun ${abs_top_builddir}/debuginfod/debuginfod-find -v debuginfo $exe; then
> + echo "$exe_info is a stripped binary, debuginfo not found, skipping"
> + continue
> + fi
> + debuginfo="`${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $exe`"
> + echo "$exe_info"
> + gprof "$debuginfo" "$f"
> + done
> +}
> --
> 2.54.0
>
More information about the Elfutils-devel
mailing list