From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id B0EEF3858C35 for ; Sat, 11 Nov 2023 22:31:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B0EEF3858C35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B0EEF3858C35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699741902; cv=none; b=fD7Mr+jo9kHlP5C/k/tdsA693KuK3msGtLnZZ513GLKNFc1/PU7wBoscHRb1gtjhZ5KJ3jN/kzCXUkZBzrNAq/1caSDkw+T7+NP9TtDVPYtke+d5Vp29C0bod1an531Z/Pq50GfC0URsiinsSbRsoVxRpmQpHsnSr7OINn+CkCU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699741902; c=relaxed/simple; bh=HcnLVwNe0qTq8MoVOtU38nVTNZB/iCrd+U1VvSa66vk=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Usirkp9rXAhSDB7bnsGWaCj7JSFsak4dTmq1rw4BI5+VMWvbEs/T+yuA7f6u6RLn4+0AhIlxSlEHJg+EOErJ/TtRx4kSByrwOP1EWe2AJImX2ubFIo2fLF+P4ZGq1LvraKxynBCpu/ElpNXwLDIpFuXi9jMNodVjeEEAjIkhSRw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1699741900; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=csNkj6WD6ntOdYEzK4aQsfl4a8NzjZg8SWzhPghwasc=; b=V2Jpt2suRzYjnmuKXqp2rMgQfyBf0PP2kEjn0sF4idLT1An+Ey1g49/8DZJ1+3xA6FzSNM AUr0ipJqrzUYlMDuILpv4HgQkDP6lD2HOl0RtHFPdqxozM5Ozp79Qs2P4dk9QN7dsra3Vs kgz8pLSHe9zHfPOqLT4taDCaWpwRxdQ= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-92-TuyJpIxDPDeDRdAA6hg_2w-1; Sat, 11 Nov 2023 17:31:38 -0500 X-MC-Unique: TuyJpIxDPDeDRdAA6hg_2w-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id F0D963813F26 for ; Sat, 11 Nov 2023 22:31:37 +0000 (UTC) Received: from f38-1.lan (unknown [10.22.16.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7E3971C060AE; Sat, 11 Nov 2023 22:31:37 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner , Andrew Burgess Subject: [PATCH 2/2] New test: gdb.base/process-dies-while-detaching.exp Date: Sat, 11 Nov 2023 15:26:29 -0700 Message-ID: <20231111223046.109727-3-kevinb@redhat.com> In-Reply-To: <20231111223046.109727-1-kevinb@redhat.com> References: <20231111223046.109727-1-kevinb@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Andrew Burgess is the primary author of this test case. Its design is similar to that of gdb.threads/main-thread-exit-during-detach.exp, which was also written by Andrew. This test checks that GDB correctly handles several cases that can occur when GDB attempts to detach an inferior process. The process can exit or be terminated (e.g. via SIGKILL) prior to GDB's event loop getting a chance to remove it from GDB's internal data structures. To complicate things even more, detach works differently when a checkpoint (created via GDB's "checkpoint" command) exists for the inferior. This test checks all four possibilities: process exit with no checkpoint, process termination with no checkpoint, process exit with a checkpoint, and process termination with a checkpoint. Co-Authored-By: Andrew Burgess --- gdb/testsuite/gdb.base/kill-during-detach.c | 32 +++++ gdb/testsuite/gdb.base/kill-during-detach.exp | 132 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 gdb/testsuite/gdb.base/kill-during-detach.c create mode 100644 gdb/testsuite/gdb.base/kill-during-detach.exp diff --git a/gdb/testsuite/gdb.base/kill-during-detach.c b/gdb/testsuite/gdb.base/kill-during-detach.c new file mode 100644 index 00000000000..2d9cca91e2f --- /dev/null +++ b/gdb/testsuite/gdb.base/kill-during-detach.c @@ -0,0 +1,32 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2023 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 . */ + +#include + +volatile int dont_exit_just_yet = 1; + +int +main () +{ + alarm (300); + + /* Spin until GDB releases us. */ + while (dont_exit_just_yet) + usleep (100000); + + _exit (0); +} diff --git a/gdb/testsuite/gdb.base/kill-during-detach.exp b/gdb/testsuite/gdb.base/kill-during-detach.exp new file mode 100644 index 00000000000..26028d5fc34 --- /dev/null +++ b/gdb/testsuite/gdb.base/kill-during-detach.exp @@ -0,0 +1,132 @@ +# Copyright 2023 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 test checks that GDB correctly handles several cases that can +# occur when GDB attempts to detach an inferior process. The process +# can exit or be terminated (e.g. via SIGKILL) prior to GDB's event +# loop getting a chance to remove it from GDB's internal data +# structures. To complicate things even more, detach works differently +# when a checkpoint (created via GDB's "checkpoint" command) exists for +# the inferior. This test checks all four possibilities: process exit +# with no checkpoint, process termination with no checkpoint, process +# exit with a checkpoint, and process termination with a checkpoint. + +standard_testfile + +# This test requires python. +require allow_python_tests + +# This test attempts to kill a process on the host running GDB, so +# disallow remote targets. (Setting --target_board to +# native-gdbserver or native-extended-gdbserver should still work.) +require {!is_remote target} + +# Checkpoint support only works on native Linux: +if { [istarget "*-*-linux*"] && [target_info gdb_protocol] == ""} { + set has_checkpoint true +} else { + set has_checkpoint false +} + +if {[build_executable "failed to prepare" $testfile $srcfile] == -1} { + return -1 +} + +# Start an inferior, which blocks in a spin loop. Setup a Python +# function that performs an action based on EXIT_P that will cause the +# inferior to exit, and then, within the same Python function, ask GDB +# to detach from the inferior. Use 'continue&' to run the inferior in +# the background, and then invoke the Python function. Note, too, that +# non-stop mode is enabled during the restart; if this is not done, +# remote_target::putpkt_binary in remote.c will disallow some of the +# operations necessary for this test. +# +# The idea is that GDB's event loop will not get a chance to handle +# the inferior exiting, so it will only be at the point that we try to +# detach that we notice that the inferior has exited. +# +# When EXIT_P is true the action we perform to terminate the inferior +# is to set a flag in the inferior, which allows the inferior to break +# out of its spin loop. +# +# When EXIT_P is false the action we perform is to send SIGKILL to the +# inferior. +# +# When CHECKPOINT_P is true, before issuing 'continue&' we use the +# 'checkpoint' command to create a checkpoint of GDB. +# +# When CHECKPOINT_P is false we don't use the 'checkpoint' command. +proc run_test { exit_p checkpoint_p } { + save_vars { ::GDBFLAGS } { + append ::GDBFLAGS " -ex \"set non-stop on\"" + clean_restart $::binfile + } + + if {![runto_main]} { + return -1 + } + + if { $checkpoint_p } { + gdb_test "checkpoint" \ + "checkpoint 1: fork returned pid $::decimal\\." + } + + # Must get the PID before we resume the inferior. + set inf_pid [get_inferior_pid] + + # Put the PID in a python variable so that a numerical PID won't + # appear in the PASS/FAIL output. + gdb_test_no_output "python inf_pid=$inf_pid" "assign inf_pid" + + gdb_test "continue &" + + if { $exit_p } { + set action_line "gdb.execute(\"set variable dont_exit_just_yet=0\")" + } else { + set action_line "os.kill(inf_pid, signal.SIGKILL)" + } + + gdb_test_multiline "Create worker function" \ + "python" "" \ + "import time" "" \ + "import os" "" \ + "import signal" "" \ + "def kill_and_detach():" "" \ + " $action_line" "" \ + " time.sleep(1)" "" \ + " gdb.execute(\"detach\")" "" \ + "end" "" + + if { $checkpoint_p } { + # NOTE: The 'checkpoint' system in GDB appears to be a little + # iffy. This detach does seem to restore the checkpoint, but + # it leaves the inferior stuck in a running state. + gdb_test_no_output "python kill_and_detach()" + } else { + gdb_test "python kill_and_detach()" \ + "\\\[Inferior $::decimal \[^\r\n\]+ detached\\\]" + } +} + +if { $has_checkpoint } { + set checkpoint_iters { true false } +} else { + set checkpoint_iters { false } +} + +foreach_with_prefix exit_p { true false } { + foreach_with_prefix checkpoint_p $checkpoint_iters { + run_test $exit_p $checkpoint_p + } +} -- 2.41.0