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 6941D3858D20 for ; Mon, 12 Jun 2023 09:53:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6941D3858D20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1686563638; 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: in-reply-to:in-reply-to:references:references; bh=4d9g/8aRdlGkcRW6UXGJ/mEncft+sluOBIu3vXA/EzU=; b=gfp8jvSK5zY2+QGnP1uX8g9i9IDFF8H5IQj0DmJTYX5Llujt2pKTMY6kz4l4T+Lyenyhm+ BZgnM71aYRc5/joarwezXyYychVR6wrXYAuUiYDFsf3ZRmTQ7cWEiAZvWaYJAE5MVKxYIX 9uiwAmcMfd2lSjbc2Lpdzmy9moMuFDA= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-172-4FXpPxq0P1quJrt7R5DswQ-1; Mon, 12 Jun 2023 05:53:56 -0400 X-MC-Unique: 4FXpPxq0P1quJrt7R5DswQ-1 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-30fad301848so1293702f8f.2 for ; Mon, 12 Jun 2023 02:53:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686563635; x=1689155635; h=mime-version:message-id:date:references:in-reply-to:subject:cc:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=4d9g/8aRdlGkcRW6UXGJ/mEncft+sluOBIu3vXA/EzU=; b=JxQAo+NtqKNF0Cqy7QZQKLlOcMkfoDrc3e70KAfNHz9dM/ZOhBRnMjZRpvAo0j04i1 JXeewBMFa/lbOzbaRBjednhlveumAn8rebdon4vKpMzZ0tYHbK1qcSMdQfpVshVtwnVY 3w4UnmLzSvjPdCUhqNKZ20BGXQG74ER92kiEMt9LC4jRgayE4H7kJWNDKTdeRpjw+2ND F8+1pYf5BE4Zmfrbs0V2Pwr8zZqyBb4joVLmKWGbme+lGWRHbGNunOeFcdnPWB5wfDta 2P/2eqBfjZTVmG+c9X58+ktpDqU4AslLHGCxxrMJtQy/Cg44OhBS8MD0OjTmBZmm9AbY BTxA== X-Gm-Message-State: AC+VfDxBgdx1KOXIcxHzN/5xiZ29fleqPi4KZj1Acy2iZskhuS+5YBhb hg94I2QkmloqPUFIeFZfxhVI2tSjYGz0tLKzhHBCMSN7/pVj998T1tBOIiOI4S0U0HhexAYR+ZD 9vA7VkIXaZV2qg+/z6o31x8eRNVXhMw== X-Received: by 2002:adf:d08e:0:b0:30f:c195:2176 with SMTP id y14-20020adfd08e000000b0030fc1952176mr1894152wrh.59.1686563635356; Mon, 12 Jun 2023 02:53:55 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6Y3uaWjg0IRPqz9w2C+lXB7uz6PQON/VItvI0hrfY3nDtByoQsINJS1/glaYn2DbAoxUTc0g== X-Received: by 2002:adf:d08e:0:b0:30f:c195:2176 with SMTP id y14-20020adfd08e000000b0030fc1952176mr1894136wrh.59.1686563634908; Mon, 12 Jun 2023 02:53:54 -0700 (PDT) Received: from localhost (2.72.115.87.dyn.plus.net. [87.115.72.2]) by smtp.gmail.com with ESMTPSA id v13-20020adfebcd000000b00309382eb047sm12053214wrn.112.2023.06.12.02.53.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Jun 2023 02:53:54 -0700 (PDT) From: Andrew Burgess To: Pedro Alves , gdb-patches@sourceware.org Cc: Pedro Alves Subject: Re: [PATCH 27/31] Testcases for stepping over thread exit syscall (PR gdb/27338) In-Reply-To: <20221212203101.1034916-28-pedro@palves.net> References: <20221212203101.1034916-1-pedro@palves.net> <20221212203101.1034916-28-pedro@palves.net> Date: Mon, 12 Jun 2023 10:53:53 +0100 Message-ID: <87cz21xaz2.fsf@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain X-Spam-Status: No, score=-12.1 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_H5,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: Pedro Alves writes: > From: Simon Marchi > > - New in this series version: > > - gdb.threads/step-over-thread-exit.exp has a couple new testing axes: > > - non-stop vs all-stop. > > - in non-stop have the testcase explicitly stop all threads in > non-stop mode, vs not doing that. > > - bail out of gdb.threads/step-over-thread-exit.exp early on FAIL, to > avoid cascading timeouts. > > Add new gdb.threads/step-over-thread-exit.exp and > gdb.threads/step-over-thread-exit-while-stop-all-threads.exp > testcases, exercising stepping over thread exit syscall. These make > use of lib/my-syscalls.S to define the exit syscall. LGTM. Reviewed-By: Andrew Burgess Thanks, Andrew > > Co-authored-by: Pedro Alves > Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27338 > Change-Id: Ie8b2c5747db99b7023463a897a8390d9e814a9c9 > --- > ...-over-thread-exit-while-stop-all-threads.c | 77 +++++++++++ > ...ver-thread-exit-while-stop-all-threads.exp | 69 ++++++++++ > .../gdb.threads/step-over-thread-exit.c | 52 ++++++++ > .../gdb.threads/step-over-thread-exit.exp | 126 ++++++++++++++++++ > gdb/testsuite/lib/my-syscalls.S | 4 + > gdb/testsuite/lib/my-syscalls.h | 5 + > 6 files changed, 333 insertions(+) > create mode 100644 gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.c > create mode 100644 gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.exp > create mode 100644 gdb/testsuite/gdb.threads/step-over-thread-exit.c > create mode 100644 gdb/testsuite/gdb.threads/step-over-thread-exit.exp > > diff --git a/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.c b/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.c > new file mode 100644 > index 00000000000..2699ad5d714 > --- /dev/null > +++ b/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.c > @@ -0,0 +1,77 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2021-2022 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 > +#include > +#include > +#include "../lib/my-syscalls.h" > + > +#define NUM_THREADS 32 > + > +static void * > +stepper_over_exit_thread (void *v) > +{ > + my_exit (0); > + > + /* my_exit above should exit the thread, we don't expect to reach > + here. */ > + abort (); > +} > + > +static void * > +spawner_thread (void *v) > +{ > + for (;;) > + { > + pthread_t threads[NUM_THREADS]; > + int i; > + > + for (i = 0; i < NUM_THREADS; i++) > + pthread_create (&threads[i], NULL, stepper_over_exit_thread, NULL); > + > + for (i = 0; i < NUM_THREADS; i++) > + pthread_join (threads[i], NULL); > + } > +} > + > +static void > +break_here (void) > +{ > +} > + > +static void * > +breakpoint_hitter_thread (void *v) > +{ > + for (;;) > + break_here (); > +} > + > +int > +main () > +{ > + pthread_t breakpoint_hitter; > + pthread_t spawner; > + > + alarm (60); > + > + pthread_create (&spawner, NULL, spawner_thread, NULL); > + pthread_create (&breakpoint_hitter, NULL, breakpoint_hitter_thread, NULL); > + > + pthread_join (spawner, NULL); > + > + return 0; > +} > diff --git a/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.exp b/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.exp > new file mode 100644 > index 00000000000..6a46aff700e > --- /dev/null > +++ b/gdb/testsuite/gdb.threads/step-over-thread-exit-while-stop-all-threads.exp > @@ -0,0 +1,69 @@ > +# Copyright 2021-2022 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 stepping over a breakpoint installed on an instruction that > +# exits the thread, while another thread is repeatedly hitting a > +# breakpoint, causing GDB to stop all threads. > + > +standard_testfile .c > + > +set syscalls_src $srcdir/lib/my-syscalls.S > + > +if { [build_executable "failed to prepare" $testfile \ > + [list $srcfile $syscalls_src] {debug pthreads}] == -1 } { > + return > +} > + > +proc test {displaced-stepping target-non-stop} { > + save_vars ::GDBFLAGS { > + append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" > + clean_restart $::binfile > + } > + > + gdb_test_no_output "set displaced-stepping ${displaced-stepping}" > + > + if { ![runto_main] } { > + return > + } > + > + # The "stepper over exit" threads will step over an instruction > + # that causes them to exit. > + gdb_test "break my_exit_syscall if 0" > + > + # The "breakpoint hitter" thread will repeatedly hit this > + # breakpoint, causing GDB to stop all threads. > + gdb_test "break break_here" > + > + # To avoid flooding the log with thread created/exited messages. > + gdb_test_no_output "set print thread-events off" > + > + # Make sure the target reports the breakpoint stops. > + gdb_test_no_output "set breakpoint condition-evaluation host" > + > + for { set i 0 } { $i < 30 } { incr i } { > + with_test_prefix "iter $i" { > + if { [gdb_test "continue" "hit Breakpoint $::decimal, break_here .*"] != 0 } { > + # Exit if there's a failure to avoid lengthy timeouts. > + break > + } > + } > + } > +} > + > +foreach_with_prefix displaced-stepping {off auto} { > + foreach_with_prefix target-non-stop {off on} { > + test ${displaced-stepping} ${target-non-stop} > + } > +} > diff --git a/gdb/testsuite/gdb.threads/step-over-thread-exit.c b/gdb/testsuite/gdb.threads/step-over-thread-exit.c > new file mode 100644 > index 00000000000..878e5924c5c > --- /dev/null > +++ b/gdb/testsuite/gdb.threads/step-over-thread-exit.c > @@ -0,0 +1,52 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2021-2022 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 > +#include > +#include > +#include "../lib/my-syscalls.h" > + > +static void * > +thread_func (void *arg) > +{ > + my_exit (0); > + > + /* my_exit above should exit the thread, we don't expect to reach > + here. */ > + abort (); > +} > + > +int > +main (void) > +{ > + int i; > + > + /* Spawn and join a thread, 100 times. */ > + for (i = 0; i < 100; i++) > + { > + pthread_t thread; > + int ret; > + > + ret = pthread_create (&thread, NULL, thread_func, NULL); > + assert (ret == 0); > + > + ret = pthread_join (thread, NULL); > + assert (ret == 0); > + } > + > + return 0; > +} > diff --git a/gdb/testsuite/gdb.threads/step-over-thread-exit.exp b/gdb/testsuite/gdb.threads/step-over-thread-exit.exp > new file mode 100644 > index 00000000000..ed8534cf518 > --- /dev/null > +++ b/gdb/testsuite/gdb.threads/step-over-thread-exit.exp > @@ -0,0 +1,126 @@ > +# Copyright 2021-2022 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 stepping over a breakpoint installed on an instruction that > +# exits the thread. > + > +standard_testfile .c > + > +set syscalls_src $srcdir/lib/my-syscalls.S > + > +if { [build_executable "failed to prepare" $testfile \ > + [list $srcfile $syscalls_src] {debug pthreads}] == -1 } { > + return > +} > + > +# Each argument is a different testing axis, most of them obvious. > +# NS_STOP_ALL is only used if testing "set non-stop on", and indicates > +# whether to have GDB explicitly stop all threads before continuing to > +# thread exit. > +proc test {displaced-stepping non-stop target-non-stop schedlock ns_stop_all} { > + if {${non-stop} == "off" && $ns_stop_all} { > + error "invalid arguments" > + } > + > + save_vars ::GDBFLAGS { > + append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" > + append ::GDBFLAGS " -ex \"set non-stop ${non-stop}\"" > + clean_restart $::binfile > + } > + > + gdb_test_no_output "set displaced-stepping ${displaced-stepping}" > + > + if { ![runto_main] } { > + return > + } > + > + gdb_breakpoint "my_exit_syscall" > + > + if {$schedlock > + || (${non-stop} == "on" && $ns_stop_all)} { > + gdb_test "continue" \ > + "Thread 2 .*hit Breakpoint $::decimal.* my_exit_syscall .*" \ > + "continue until syscall" > + > + if {${non-stop} == "on"} { > + # The test only spawns one thread at a time, so this just > + # stops the main thread. > + gdb_test_multiple "interrupt -a" "" { > + -re "$::gdb_prompt " { > + gdb_test_multiple "" $gdb_test_name { > + -re "Thread 1 \[^\r\n\]*stopped." { > + pass $gdb_test_name > + } > + } > + } > + } > + } > + > + gdb_test "thread 2" "Switching to thread 2 .*" > + > + gdb_test_no_output "set scheduler-locking ${schedlock}" > + > + gdb_test "continue" \ > + "No unwaited-for children left." \ > + "continue stops when thread exits" > + } else { > + gdb_test_no_output "set scheduler-locking ${schedlock}" > + > + for { set i 0 } { $i < 100 } { incr i } { > + with_test_prefix "iter $i" { > + set ok 0 > + set thread "" > + gdb_test_multiple "continue" "" { > + -re -wrap "Thread ($::decimal) .*hit Breakpoint $::decimal.* my_exit_syscall .*" { > + set thread $expect_out(1,string) > + set ok 1 > + } > + } > + if {!${ok}} { > + # Exit if there's a failure to avoid lengthy > + # timeouts. > + break > + } > + > + if {${non-stop}} { > + gdb_test "thread $thread" "Switching to thread .*" \ > + "switch to event thread" > + } > + } > + } > + } > +} > + > +foreach_with_prefix displaced-stepping {off auto} { > + foreach_with_prefix non-stop {off on} { > + foreach_with_prefix target-non-stop {off on} { > + if {${non-stop} == "on" && ${target-non-stop} == "off"} { > + # Invalid combination. > + continue > + } > + > + foreach_with_prefix schedlock {off on} { > + if {${non-stop} == "on"} { > + foreach_with_prefix ns_stop_all {0 1} { > + test ${displaced-stepping} ${non-stop} ${target-non-stop} \ > + ${schedlock} ${ns_stop_all} > + } > + } else { > + test ${displaced-stepping} ${non-stop} ${target-non-stop} ${schedlock} 0 > + } > + } > + } > + } > +} > diff --git a/gdb/testsuite/lib/my-syscalls.S b/gdb/testsuite/lib/my-syscalls.S > index 6fb53624f31..ff62b5eb4e9 100644 > --- a/gdb/testsuite/lib/my-syscalls.S > +++ b/gdb/testsuite/lib/my-syscalls.S > @@ -69,4 +69,8 @@ NAME ## _syscall: ;\ > > SYSCALL (my_execve, __NR_execve) > > +/* void my_exit (int code); */ > + > +SYSCALL (my_exit, __NR_exit) > + > .section .note.GNU-stack,"",@progbits > diff --git a/gdb/testsuite/lib/my-syscalls.h b/gdb/testsuite/lib/my-syscalls.h > index a0c069c58e5..ceaa587b3e6 100644 > --- a/gdb/testsuite/lib/my-syscalls.h > +++ b/gdb/testsuite/lib/my-syscalls.h > @@ -22,4 +22,9 @@ > > int my_execve (const char *file, char *argv[], char *envp[]); > > +/* `exit` syscall, which makes the thread exit (as opposed to > + `exit_group`, which makes the process exit). */ > + > +void my_exit (int code); > + > #endif /* MY_SYSCALLS_H */ > -- > 2.36.0