From 7e42bbed5b11c30330b722d78eec3b2004f1a918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= Date: Fri, 2 Feb 2024 11:13:47 +0100 Subject: [PATCH] Add a test for the gcore script It also tests the gcore script being run without its accessible terminal. This test was written by Jan Kratochvil a long time ago. I modernized the test making it use various procs from lib/gdb.exp, reorganizing it and added some comments. Modify the gcore script to make it possible to pass the --data-directory to it. This prevents a lot of these warnings: Python Exception : module 'gdb' has no attribute '_handle_missing_debuginfo' Tested by using make check-all-boards. Co-Authored-By: Jan Kratochvil Reviewed-By: Eli Zaretskii --- gdb/doc/gdb.texinfo | 6 ++- gdb/gcore.in | 12 +++-- gdb/testsuite/gdb.base/gcorebg.c | 76 +++++++++++++++++++++++++++ gdb/testsuite/gdb.base/gcorebg.exp | 82 ++++++++++++++++++++++++++++++ gdb/testsuite/lib/gdb.exp | 17 +++++++ 5 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 gdb/testsuite/gdb.base/gcorebg.c create mode 100644 gdb/testsuite/gdb.base/gcorebg.exp diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 147b8d4c24e..b900b5d2965 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -51032,7 +51032,7 @@ Richard M. Stallman and Roland H. Pesch, July 1991. @format @c man begin SYNOPSIS gcore -gcore [-a] [-o @var{prefix}] @var{pid1} [@var{pid2}...@var{pidN}] +gcore [-a] [-o @var{prefix}] [-d @var{directory}] @var{pid1} [@var{pid2}...@var{pidN}] @c man end @end format @@ -51060,6 +51060,10 @@ when composing the file names of the core dumps. The file name is composed as @file{@var{prefix}.@var{pid}}, where @var{pid} is the process ID of the running program being analyzed by @command{gcore}. If not specified, @var{prefix} defaults to @var{gcore}. + +@item -d @var{directory} +Use @var{directory} as the data directory when invoking @value{GDBN} for running +the gcore command. This argument is optional. @end table @c man end diff --git a/gdb/gcore.in b/gdb/gcore.in index 982c854eb70..0c40e5a54cd 100644 --- a/gdb/gcore.in +++ b/gdb/gcore.in @@ -27,7 +27,9 @@ prefix=core # to ensure gdb dumps all mappings (OS dependent). dump_all_cmds=() -while getopts :ao: opt; do +data_directory_opt=() + +while getopts :ao:d: opt; do case "$opt" in a) case "$OSTYPE" in @@ -40,8 +42,11 @@ while getopts :ao: opt; do o) prefix=$OPTARG ;; + d) + data_directory_opt=("--data-directory" "$OPTARG") + ;; *) - echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] pid1 [pid2...pidN]" + echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] [-d data-directory] pid1 [pid2...pidN]" exit 2 ;; esac @@ -51,7 +56,7 @@ shift $((OPTIND-1)) if [ "$#" -eq "0" ] then - echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] pid1 [pid2...pidN]" + echo "usage: @GCORE_TRANSFORM_NAME@ [-a] [-o prefix] [-d data-directory] pid1 [pid2...pidN]" exit 2 fi @@ -98,6 +103,7 @@ do # `. */ + +#include +#include +#include +#include +#include +#include +#include + +/* Expects 4 arguments: + + 1. Either 'standard' or 'detached', where 'standard' tests + a general gcore script spawn with its controlling terminal available + and 'detached' tests gcore script spawn without its controlling + terminal available. + 2. Path to the gcore script. + 3. Path to the data-directory to pass to the gcore script. + 4. The core file output name. */ + +int +main (int argc, char **argv) +{ + pid_t pid = 0; + pid_t ppid; + char buf[1024*2 + 500]; + int gotint, res; + + assert (argc == 5); + + pid = fork (); + + switch (pid) + { + case 0: + if (strcmp (argv[1], "detached") == 0) + setpgrp (); + ppid = getppid (); + gotint = snprintf (buf, sizeof (buf), "%s -d %s -o %s %d", + argv[2], argv[3], argv[4], (int) ppid); + assert (gotint < sizeof (buf)); + res = system (buf); + assert (res != -1); + break; + + case -1: + perror ("fork err\n"); + exit (1); + break; + + default: + do + { + res = waitpid (pid, NULL, 0); + } + while (res == -1 && errno == EINTR); + + assert (res == pid); + break; + } + + return 0; +} diff --git a/gdb/testsuite/gdb.base/gcorebg.exp b/gdb/testsuite/gdb.base/gcorebg.exp new file mode 100644 index 00000000000..c271251b7df --- /dev/null +++ b/gdb/testsuite/gdb.base/gcorebg.exp @@ -0,0 +1,82 @@ +# Copyright 2007-2024 Free Software Foundation, Inc. +# +# 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 . +# +# This is a test for the gcore script (not the gcore command from +# inside GDB). It also tests the gcore script being run without its +# accessible terminal. + +standard_testfile +require {!is_remote host} +require {!is_remote target} +require has_gcore_script +require can_spawn_for_attach + +set corefile [standard_output_file ${testfile}.core] + +if {[build_executable "failed to build" $testfile ${srcfile}] == -1 } { + return -1 +} + +# Cleanup. + +proc core_clean {} { + global corefile + + foreach file [glob -nocomplain [join [list $corefile *] ""]] { + verbose "Delete file $file" 1 + remote_file target delete $file + } +} +core_clean + +# Generate the core file. +proc test_body { detached } { + global binfile + global GCORE + global corefile + global GDB_DATA_DIRECTORY + + # We can't use gdb_test_multiple here because GDB is not started. + set res [remote_spawn target "$binfile $detached $GCORE $GDB_DATA_DIRECTORY $corefile"] + if { ![gdb_assert { ![expr {$res < 0 || $res == ""}] } \ + "spawned gcore"] } { + return + } + + set saw_corefile_created false + set testname "Spawned gcore finished" + remote_expect target 20 { + timeout { + fail "$testname (timeout)" + remote_exec target "kill -9 -[exp_pid -i $res]" + return + } + -re "Saved corefile \[^\r\n\]+\r\n" { + set saw_corefile_created true + exp_continue + } + eof { + gdb_assert { $saw_corefile_created } $testname + } + } + + gdb_assert {1 == [llength [glob -nocomplain [join [list $corefile *] ""]]]}\ + "Core file generated by gcore" + core_clean +} + +foreach_with_prefix detached { detached standard } { + test_body $detached +} diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index b3e1f306a29..8ca4b00cbfa 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -158,6 +158,23 @@ load_lib gdb-utils.exp load_lib memory.exp load_lib check-test-names.exp +# The path to the GCORE script to test. +global GCORE +if {![info exists GCORE]} { + set GCORE [findfile $base_dir/../../gdb/gcore] +} +verbose "using GCORE = $GCORE" 2 + +# Return 0 if the gcore scipt is missing. +proc has_gcore_script {} { + global GCORE + if {$GCORE == ""} { + return 0 + } else { + return 1 + } +} + # The path to the GDB binary to test. global GDB