gdb/testsuite: add test for run/attach while program is running
A WIP 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
This commit is contained in:
parent
95557f1e09
commit
d0c99a23b2
@ -1,3 +1,9 @@
|
|||||||
|
2021-03-17 Simon Marchi <simon.marchi@polymtl.ca>
|
||||||
|
Pedro Alves <pedro@palves.net>
|
||||||
|
|
||||||
|
* gdb.base/run-attach-while-running.exp: New.
|
||||||
|
* gdb.base/run-attach-while-running.c: New.
|
||||||
|
|
||||||
2021-03-16 Andrew Burgess <andrew.burgess@embecosm.com>
|
2021-03-16 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
* gdb.python/py-framefilter-addr.c: New file.
|
* gdb.python/py-framefilter-addr.c: New file.
|
||||||
|
69
gdb/testsuite/gdb.base/run-attach-while-running.c
Normal file
69
gdb/testsuite/gdb.base/run-attach-while-running.c
Normal file
@ -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;
|
||||||
|
}
|
120
gdb/testsuite/gdb.base/run-attach-while-running.exp
Normal file
120
gdb/testsuite/gdb.base/run-attach-while-running.exp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
# 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
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach_with_prefix threaded {0 1} {
|
||||||
|
set options [list debug additional_flags=-DWITH_THREADS=$threaded]
|
||||||
|
if { $threaded } {
|
||||||
|
set binfile $binfile_threads
|
||||||
|
lappend options pthreads
|
||||||
|
} else {
|
||||||
|
set binfile $binfile_nothreads
|
||||||
|
}
|
||||||
|
if { [build_executable "failed to prepare" ${binfile} ${srcfile} $options] } {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach_with_prefix run-or-attach {run attach} {
|
||||||
|
foreach_with_prefix non-stop {off on} {
|
||||||
|
test ${non-stop} ${threaded} ${run-or-attach}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user