]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
tests/: add test suite for stackprof
authorSerhei Makarov <serhei@serhei.io>
Mon, 13 Apr 2026 18:46:02 +0000 (14:46 -0400)
committerSerhei Makarov <serhei@serhei.io>
Wed, 24 Jun 2026 20:46:27 +0000 (16:46 -0400)
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
tests/run-stackprof-system-gprof.sh [new file with mode: 0755]
tests/run-stackprof-system.sh [new file with mode: 0755]
tests/run-stackprof-user-gprof.sh [new file with mode: 0755]
tests/run-stackprof-user.sh [new file with mode: 0755]
tests/stackprof-subr.sh [new file with mode: 0644]

index 8ae7d126636e96dbc25da61d1a83699accec1e9e..f098d31fe250b4a6afa2d71362e60e2ab2ee3c5a 100644 (file)
@@ -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 \
             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 (executable)
index 0000000..c281167
--- /dev/null
@@ -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 (executable)
index 0000000..cb796a7
--- /dev/null
@@ -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 (executable)
index 0000000..9360f8b
--- /dev/null
@@ -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 (executable)
index 0000000..722b7b0
--- /dev/null
@@ -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
+    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 (file)
index 0000000..729053d
--- /dev/null
@@ -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
+            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
+}