public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Simon Marchi <simon.marchi@polymtl.ca>
To: gdb-patches@sourceware.org
Subject: [PATCH v4 1/3] gdb/testsuite: add test for run/attach while program is running
Date: Sun, 24 Jan 2021 23:57:28 -0500	[thread overview]
Message-ID: <20210125045730.1739754-2-simon.marchi@polymtl.ca> (raw)
In-Reply-To: <20210125045730.1739754-1-simon.marchi@polymtl.ca>

A previous version of this patch series broke the use case of doing
"run" or "attach" while the program is running, but it wasn't caught by
the testsuite, which means it's not covered.  Add a test for that.

gdb/testsuite/ChangeLog:

	* gdb.base/run-attach-while-running.exp: New.
	* gdb.base/run-attach-while-running.c: New.

Change-Id: I77f098ec0b28dc2d4575ea80e941f6a75273e431
---
 .../gdb.base/run-attach-while-running.c       |  69 +++++++++
 .../gdb.base/run-attach-while-running.exp     | 131 ++++++++++++++++++
 2 files changed, 200 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/run-attach-while-running.c
 create mode 100644 gdb/testsuite/gdb.base/run-attach-while-running.exp

diff --git a/gdb/testsuite/gdb.base/run-attach-while-running.c b/gdb/testsuite/gdb.base/run-attach-while-running.c
new file mode 100644
index 000000000000..57bebbe6456e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/run-attach-while-running.c
@@ -0,0 +1,69 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2021 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 <http://www.gnu.org/licenses/>.  */
+
+#include <unistd.h>
+#include <assert.h>
+
+#ifndef WITH_THREADS
+# error "WITH_THREADS must be defined."
+#endif
+
+#if WITH_THREADS
+# include <pthread.h>
+
+static pthread_barrier_t barrier;
+
+static void *
+thread_func (void *p)
+{
+  pthread_barrier_wait (&barrier);
+
+  for (int i = 0; i < 30; i++)
+    sleep (1);
+
+  return NULL;
+}
+
+#endif /* WITH_THREADS */
+
+static void
+all_started (void)
+{}
+
+int
+main (void)
+{
+  alarm (30);
+
+#if WITH_THREADS
+  int ret = pthread_barrier_init (&barrier, NULL, 2);
+  assert (ret == 0);
+
+  pthread_t thread;
+  ret = pthread_create (&thread, NULL, thread_func, NULL);
+  assert (ret == 0);
+
+  pthread_barrier_wait (&barrier);
+#endif /* WITH_THREADS */
+
+  all_started ();
+
+  for (int i = 0; i < 30; i++)
+    sleep (1);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/run-attach-while-running.exp b/gdb/testsuite/gdb.base/run-attach-while-running.exp
new file mode 100644
index 000000000000..385bbc410dbf
--- /dev/null
+++ b/gdb/testsuite/gdb.base/run-attach-while-running.exp
@@ -0,0 +1,131 @@
+# Copyright 2021 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 <http://www.gnu.org/licenses/>.
+
+# Test doing a "run" or an "attach" while the program is running.
+#
+# We test a non-threaded and a threaded configuration, so that targets that
+# don't support threads get some testing, but we also test with threads when
+# possible in case that triggers some multi-thread-specific bugs.
+
+standard_testfile
+
+set binfile_threads ${binfile}-threads
+set binfile_nothreads ${binfile}-nothreads
+unset binfile
+
+# Valid parameter / axis values:
+#
+#   - non-stop: "off" of "on"
+#   - threaded: 0 or 1
+#   - run-or-attach: "run" or "attach"
+
+proc_with_prefix test { non-stop threaded run-or-attach } {
+    if { ${run-or-attach} == "attach" && ![can_spawn_for_attach] } {
+	unsupported "attach not supported"
+	return
+    }
+
+    # Choose the right (threaded or not) binfile.
+    if { $threaded } {
+	set binfile $::binfile_threads
+    } else {
+	set binfile $::binfile_nothreads
+    }
+
+    save_vars ::GDBFLAGS {
+	set ::GDBFLAGS "$::GDBFLAGS -ex \"set non-stop ${non-stop}\""
+
+	# The test doesn't work when the remote target uses the synchronous
+	# remote protocol, because GDB can't kill the remote inferior while it
+	# is running, when we "run" or "attach" again.  When aswering "yes" to
+	# the "Start it from the beginning?" question, we otherwise get:
+	#
+	#   Cannot execute this command while the target is running.  Use the
+	#   "interrupt" command to stop the target and then try again.
+	#
+	# Interrupting the target would defeat the purpose of the test.  So
+	# when non-stop is off and using the remote target, force the target
+	# to use the async / non-stop version of the protocol.
+	if { [target_info exists gdb_protocol] && ${non-stop} == "off" } {
+	    set ::GDBFLAGS "$::GDBFLAGS -ex \"maint set target-non-stop on\""
+	}
+
+	clean_restart $binfile
+    }
+
+    if { ![runto_main] } {
+	untested "could not run to main"
+	return
+    }
+
+    gdb_breakpoint "all_started" "temporary"
+    gdb_continue_to_breakpoint "continue to all_started"
+
+    # If all-stop, everything stopped when we hit the all_started breakpoint,
+    # so resume execution in background.  If running the non-threaded version,
+    # our only thread is stopped in any case, so resume as well.  But if we are
+    # in non-stop with two threads, we have one running and one stopped, leave
+    # it like this, it makes an interesting test case.
+    if { ${non-stop} == "off" || !${threaded} } {
+	gdb_test "continue &" "Continuing."
+    }
+
+    gdb_test_no_output "set confirm off"
+
+    # Run again (or, connect to a new stub if using a stub), take advantage
+    # of the fact that runto_main leaves the breakpoint on main in place.
+    if { ${run-or-attach} == "run" } {
+	gdb_run_cmd
+	gdb_test "" "Breakpoint $::decimal, .*main.*" "hit main breakpoint after re-run"
+    } elseif { ${run-or-attach} == "attach" } {
+	set test_spawn_id [spawn_wait_for_attach $binfile]
+	set test_pid [spawn_id_get_pid $test_spawn_id]
+
+	gdb_test "attach $test_pid" "Attaching to program: .*" "attach to process"
+
+	gdb_exit
+	kill_wait_spawned_process $test_spawn_id
+    } else {
+	error "Invalid value for run-or-attach"
+    }
+}
+
+# Build and test with the non-threaded version.
+if { [build_executable "failed to prepare" ${binfile_nothreads} ${srcfile} \
+      {debug additional_flags=-DWITH_THREADS=0} ] } {
+    return
+}
+
+with_test_prefix {threaded=0} {
+    foreach_with_prefix run-or-attach {run attach} {
+	foreach_with_prefix non-stop {off on} {
+	    test ${non-stop} 0 ${run-or-attach}
+	}
+    }
+}
+
+# Build and test with the threaded version.
+if { [build_executable "failed to prepare" ${binfile_threads} ${srcfile} \
+      {debug pthreads additional_flags=-DWITH_THREADS=1} ] } {
+    return
+}
+
+with_test_prefix {threaded=1} {
+    foreach_with_prefix run-or-attach {run attach} {
+	foreach_with_prefix non-stop {off on} {
+	    test ${non-stop} 1 ${run-or-attach}
+	}
+    }
+}
-- 
2.30.0


  reply	other threads:[~2021-01-25  4:57 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-25  4:57 [PATCH v4 0/3] Reduce back and forth with target when threads have pending statuses Simon Marchi
2021-01-25  4:57 ` Simon Marchi [this message]
2021-02-06 18:22   ` [PATCH v4 1/3] gdb/testsuite: add test for run/attach while program is running Pedro Alves
2021-03-17 12:52     ` Pedro Alves
2021-01-25  4:57 ` [PATCH v4 2/3] gdb: move commit_resume to process_stratum_target Simon Marchi
2021-01-25  4:57 ` [PATCH v4 3/3] gdb: generalize commit_resume, avoid commit-resuming when threads have pending statuses Simon Marchi
2021-02-06 18:05   ` Pedro Alves
2021-02-03  1:35 ` [PATCH v4 0/3] Reduce back and forth with target " Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210125045730.1739754-2-simon.marchi@polymtl.ca \
    --to=simon.marchi@polymtl.ca \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).