From patchwork Fri Oct 11 15:16:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Seitz X-Patchwork-Id: 98747 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3A525385772C for ; Fri, 11 Oct 2024 15:17:03 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 066693858D26 for ; Fri, 11 Oct 2024 15:16:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 066693858D26 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 066693858D26 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=1728659799; cv=none; b=FCGNMf0K+p9zsvBmufLeYYM8lTL8zreSFBjhzCpuDvJpRqgYka4RouNO5+yzfSs2KX0/kftJMSzj67oyLEsPQmJO8oUq9vzOoUsQg07kOrwtw+uhWGG/8QYJkh3nSc2tJmQ9aeM485hScQAnaqbucBz8Oc5NEPQOLNPaB8uVi34= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1728659799; c=relaxed/simple; bh=7QvhhVv9PiBrAkL1QxFjwpxlZJsBoZb+gBLOopnDvd0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=rAcsvc5EgbX0v7xEwoI7pM2Cs9Vxmh/ch2x+CeqoJKPiFvJH/jUHTNUc2hvukSuvpzPyk8P3Io8N0BSPMBj/+c/ULtXLnkmDhH47Yt5YALQYJSJpY4scQn9BXPe0y2RPXyJupHm13v0Tx1l9kEshLc+BNMWPYkALJZevb8H8u/c= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728659796; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=3FfTUJa6RwwUJ2L2kHkfBlLWZjUhwWHkijl5UmLycww=; b=hAN2zNL4DiSAp0HMaoPY2WuYFeredaJ8vlFyyaa8zds3TrZ3Xpks+cObkIG0JRf0/iKyFd hHpeaxO4BxsBcezY4balEP7rQePMDbr4oY6GkDGIW/81YxEJ4h8E071n25swQH4iT7LU9a bI67NAxSGQQDRs0zSKmTr1+FE8fWjeE= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-636-S0uPVNXPNt-nyum25K1v0g-1; Fri, 11 Oct 2024 11:16:33 -0400 X-MC-Unique: S0uPVNXPNt-nyum25K1v0g-1 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (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 mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A69931955DCD for ; Fri, 11 Oct 2024 15:16:32 +0000 (UTC) Received: from guittard.uglyboxes.com (unknown [10.22.33.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 08A1230001A3 for ; Fri, 11 Oct 2024 15:16:31 +0000 (UTC) From: Keith Seitz To: gdb-patches@sourceware.org Subject: [PATCH] Add syscall tests when following/detaching from fork Date: Fri, 11 Oct 2024 08:16:30 -0700 Message-ID: <2058105a557942a6e8c0765d32cc8ee715c2d1eb.1728659790.git.keiths@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.2 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 autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org breakpoints/13457 discusses issues with syscall catchpoints when following forks, lamenting that there is no coverage for the various permutations of `follow-fork-mode' and `detach-on-fork'. This is an attempt to try and cover some of this ground, demonstrating the failure of gdb/gdbserver to properly handle the cases where it stays attached to both parent and child. According to my testing (both with this test and manually), the results of this testing are architecture-dependent. For example, gdbserver on s390x and ppc64le fails some tests which pass on other arches. Given the ubiquity of x86_64, I've added KFAILs based on that architecture, but I wonder if that's necessary (or even desired). Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=13457 --- gdb/testsuite/gdb.base/foll-fork-syscall.c | 18 +++ gdb/testsuite/gdb.base/foll-fork-syscall.exp | 150 +++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 gdb/testsuite/gdb.base/foll-fork-syscall.c create mode 100644 gdb/testsuite/gdb.base/foll-fork-syscall.exp base-commit: 753e2f771b1bba72426354aef364c8d986ed999c diff --git a/gdb/testsuite/gdb.base/foll-fork-syscall.c b/gdb/testsuite/gdb.base/foll-fork-syscall.c new file mode 100644 index 00000000000..dd7df4b87df --- /dev/null +++ b/gdb/testsuite/gdb.base/foll-fork-syscall.c @@ -0,0 +1,18 @@ +#include +#include + +int +main (int argc, char **argv) +{ + int pid, x = 0; + + pid = fork (); + if (pid == 0) /* set breakpoint here */ + printf ("I am the child\n"); + else + printf ("I am the parent\n"); + + chdir ("."); + ++x; /* set exit breakpoint here */ + return 0; +} diff --git a/gdb/testsuite/gdb.base/foll-fork-syscall.exp b/gdb/testsuite/gdb.base/foll-fork-syscall.exp new file mode 100644 index 00000000000..56a04b1777c --- /dev/null +++ b/gdb/testsuite/gdb.base/foll-fork-syscall.exp @@ -0,0 +1,150 @@ +# Copyright 1997-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 . + +# Test catching syscalls with all permutations of follow-fork parent/child +# and detach-on-fork on/off. + +# Test relies on checking follow-fork output. Do not run if gdb debug is +# enabled because it will be redirected to the log. +require !gdb_debug_enabled + +standard_testfile + +if {[build_executable "failed to prepare" $testfile $srcfile debug]} { + return -1 +} + +proc setup_gdb {} { + global testfile + + clean_restart $testfile + + if {![runto_main]} { + return false + } + + # Set a breakpoint after the fork is "complete." + if {![gdb_breakpoint [gdb_get_line_number "set breakpoint here"]]} { + return false + } + + # Set exit breakpoint (to prevent inferior from exiting). + if {![gdb_breakpoint [gdb_get_line_number "set exit breakpoint here"]]} { + return false + } + return true +} + +# Check that fork catchpoints are supported, as an indicator for whether +# fork-following is supported. Return 1 if they are, else 0. + +proc_with_prefix check_fork_catchpoints {} { + global gdb_prompt + + if { ![setup_gdb] } { + return false + } + + # Verify that the system supports "catch fork". + gdb_test "catch fork" "Catchpoint \[0-9\]* \\(fork\\)" "insert first fork catchpoint" + set has_fork_catchpoints false + gdb_test_multiple "continue" "continue to first fork catchpoint" { + -re ".*Your system does not support this type\r\nof catchpoint.*$gdb_prompt $" { + unsupported "continue to first fork catchpoint" + } + -re ".*Catchpoint.*$gdb_prompt $" { + set has_fork_catchpoints true + pass "continue to first fork catchpoint" + } + } + + return $has_fork_catchpoints +} + +proc_with_prefix test_catch_syscall {follow-fork-mode detach-on-fork kfail} { + # Start with shiny new gdb instance. + if {![setup_gdb]} { + return + } + + # The "Detaching..." and "Attaching..." messages may be hidden by + # default. + gdb_test_no_output "set verbose" + + # Setup modes to test. + gdb_test_no_output "set follow-fork-mode ${follow-fork-mode}" + gdb_test_no_output "set detach-on-fork ${detach-on-fork}" + + gdb_test "catch fork" "Catchpoint . \\(fork\\)" + gdb_test "catch syscall chdir" "Catchpoint . \\(syscall 'chdir'.*\\)" + + # Which inferior we're expecting to follow. Assuming the parent + # will be inferior #1, and the child will be inferior #2. + if {${follow-fork-mode} == "parent"} { + set following_inf 1 + } else { + set followin_inf 2 + } + # Next stop should be the fork catchpoint. + set expected_re "" + append expected_re "Catchpoint . \\(forked process.*" + gdb_test "continue" $expected_re "continue to fork catchpoint" + + # Next stop should be the breakpoint after the fork. + set expected_re ".*" + if {${follow-fork-mode} == "child" || ${detach-on-fork} == "off"} { + append expected_re "\\\[New inferior.*" + } + if {${detach-on-fork} == "on"} { + append expected_re "\\\[Detaching after fork from " + if {${follow-fork-mode} == "parent"} { + append expected_re "child" + } else { + append expected_re "parent" + } + append expected_re " process.*" + } + append expected_re "Breakpoint .*set breakpoint here.*" + gdb_test "continue" $expected_re "continue to breakpoint after fork" + + # Next stop should be the syscall catchpoint. + set expected_re ".*Catchpoint . \\(call to syscall chdir\\).*" + if {$kfail != ""} { + eval setup_kfail $kfail + } + gdb_test continue $expected_re "continue to chdir syscall" +} + +# Array of results which expect to fail. +array set kfail_array { + {parent on} "" + {parent off} "breakpoints/13457 *-*-*" + {child on} "" + {child off} "breakpoints/13457 *-*-*" +} + +# Check for follow-fork support. +if {![check_fork_catchpoints]} { + untested "follow-fork not supported" + return +} + +# Test all permutations. +foreach_with_prefix follow-fork-mode {"parent" "child"} { + foreach_with_prefix detach-on-fork {"on" "off"} { + test_catch_syscall ${follow-fork-mode} ${detach-on-fork} \ + $kfail_array(${follow-fork-mode} ${detach-on-fork}) + } +}