From: Paul Floyd Date: Tue, 13 May 2025 18:34:48 +0000 (+0200) Subject: Bug 504101 - Add a "vgstack" script X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=568ce38ac76e1cefc20b006c7da8cf7bf2209596;p=thirdparty%2Fvalgrind.git Bug 504101 - Add a "vgstack" script This works just like pstack/gstack (and bstack on FreeBSD). Run "vgstack [valgrind pid]" and you will get the guest backtraces. --- diff --git a/.gitignore b/.gitignore index fa0fa0d34..962c97606 100644 --- a/.gitignore +++ b/.gitignore @@ -178,6 +178,7 @@ /coregrind/valgrind /coregrind/vgdb /coregrind/vgpreload_core-x86-darwin.so.dSYM +/coregrind/vgstack /coregrind/vg_intercept.c /coregrind/vg_replace_malloc.c /coregrind/vg_toolint.c diff --git a/NEWS b/NEWS index a1833ad40..065f32fd5 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 503677 duplicated-cond compiler warning in dis_RV64M 503817 s390x: fix 'ordered comparison of pointer with integer zero' compiler warnings 503914 mount syscall param filesystemtype may be NULL +504101 Add a "vgstack" script 504177 FILE DESCRIPTORS banner shows when closing some inherited fds To see details of a given bug, visit diff --git a/configure.ac b/configure.ac index 84a69f810..00cf62d47 100755 --- a/configure.ac +++ b/configure.ac @@ -5692,7 +5692,8 @@ AC_CONFIG_FILES([ include/Makefile auxprogs/Makefile mpi/Makefile - coregrind/Makefile + coregrind/Makefile + coregrind/vgstack memcheck/Makefile memcheck/tests/Makefile memcheck/tests/common/Makefile diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index 700751dea..784459569 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -34,6 +34,8 @@ bin_PROGRAMS = \ valgrind \ vgdb +bin_SCRIPTS = vgstack + if VGCONF_OS_IS_LINUX valgrind_SOURCES = \ launcher-linux.c \ diff --git a/coregrind/vgstack.in b/coregrind/vgstack.in new file mode 100755 index 000000000..75ed868e9 --- /dev/null +++ b/coregrind/vgstack.in @@ -0,0 +1,158 @@ +#!/bin/sh + +# Copyright (C) 2024-2025 Free Software Foundation, Inc. +# Copyright (C) 2025 Paul Floyd +# pjfloyd@wanadoo.fr + +# This program 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. +# +# This program 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 . + +# Print a stack trace of a running process. +# Similar to the gcore command, but instead of creating a core file, +# we simply have gdb print out the stack backtrace to the terminal. + +# This script is largely based on gstack/pstack from gdb. +# There is a bit of extra filtering to remove gdb warnings, +# the shell used is /bin/sh rather than bash. +# The main functional change is that it 'uses target remote | vgdb' +# instead of 'attach'. + +GDB=${GDB:-$(command -v gdb)} +GDBARGS=${GDBARGS:-} +AWK=${AWK:-} +VERSION="@VERSION@" + +# Find an appropriate awk interpreter if one was not specified +# via the environment. +awk_prog="" +if [ -z "$AWK" ]; then + for prog in gawk mawk nawk awk; do + awk_prog=$(command -v $prog) + test -n "$awk_prog" && break + done + AWK="$awk_prog" +fi +if [ ! -x "$AWK" ]; then + echo "$0: could not find usable awk interpreter" 1>&2 + exit 2 +fi + +print_usage() { + echo "Usage: $0 [-h|--help] [-v|--version] PID" +} + +print_try_help() { + echo "Try '$0 --help' for more information." +} + +print_help() { + print_usage + echo "Print a stack trace of a running program" + echo + echo " -h, --help Print this message then exit." + echo " -v, --version Print version information then exit." +} + +print_version() { + echo "${0}-${VERSION}" +} + +# Parse options. +while getopts hv-: OPT; do + if [ "$OPT" = "-" ]; then + OPT="${OPTARG%%=*}" + OPTARG="${OPTARG#'$OPT'}" + OPTARG="${OPTARG#=}" + fi + + case "$OPT" in + h | help) + print_help + exit 0 + ;; + v | version) + print_version + exit 0 + ;; + \?) + # getopts has already output an error message. + print_try_help 1>&2 + exit 2 ;; + *) + echo "$0: unrecognized option '--$OPT'" 1>&2 + print_try_help 1>&2 + exit 2 + ;; + esac +done +shift $((OPTIND-1)) + +# The sole remaining argument should be the PID of the process +# whose backtrace is desired. +if [ $# -ne 1 ]; then + print_usage 1>&2 + exit 1 +fi + +PID=$1 + +awk_script=$(cat << EOF +BEGIN { + first=1 + attach_okay=0 +} + +/ATTACHED/ { + attach_okay=1 +} + +/^#/ { + if (attach_okay) { + print \$0 + } +} + +/^Thread/ { + if (attach_okay) { + if (first == 0) + print "" + first=0 + print \$0 + } +} + +/warning:/ { + next +} + +END { +if (attach_okay == 0) + exit 2 +} +EOF + ) + +# Run GDB and remove some unwanted noise. +"$GDB" --quiet -nx $GDBARGS <&1 | +set width 0 +set height 0 +set pagination no +set debuginfod enabled off +define vgdb-bt +target remote | vgdb --pid=\$arg0 +echo "ATTACHED" +thread apply all bt +end +vgdb-bt $PID +EOF +$AWK -- "$awk_script"