diff options
-rw-r--r-- | gdb/ChangeLog | 13 | ||||
-rw-r--r-- | gdb/exec.c | 5 | ||||
-rw-r--r-- | gdb/infrun.c | 16 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.multi/multi-re-run-1.c | 61 | ||||
-rw-r--r-- | gdb/testsuite/gdb.multi/multi-re-run-2.c | 61 | ||||
-rw-r--r-- | gdb/testsuite/gdb.multi/multi-re-run.exp | 115 | ||||
-rw-r--r-- | gdb/thread.c | 5 |
8 files changed, 265 insertions, 18 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3d166f0..16d16ef 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2020-01-24 Pedro Alves <palves@redhat.com> + + PR gdb/25410 + * thread.c (scoped_restore_current_thread::restore): Use + switch_to_inferior_no_thread. + * exec.c: Include "progspace-and-thread.h". + (add_target_sections, remove_target_sections): + scoped_restore_current_pspace_and_thread instead of + scoped_restore_current_thread. + * infrun.c (handle_vfork_child_exec_or_exit): Assign the pspace + and aspace to the inferior before calling clone_program_space. + Remove stale comment. + 2020-01-24 Christian Biesinger <cbiesinger@google.com> * arm-nbsd-nat.c (arm_nbsd_nat_target::fetch_registers): Rename to... @@ -33,6 +33,7 @@ #include "arch-utils.h" #include "gdbthread.h" #include "progspace.h" +#include "progspace-and-thread.h" #include "gdb_bfd.h" #include "gcore.h" #include "source.h" @@ -547,7 +548,7 @@ add_target_sections (void *owner, table->sections[space + i].owner = owner; } - scoped_restore_current_thread restore_thread; + scoped_restore_current_pspace_and_thread restore_pspace_thread; program_space *curr_pspace = current_program_space; /* If these are the first file sections we can provide memory @@ -645,7 +646,7 @@ remove_target_sections (void *owner) inferior sharing the program space. */ if (old_count + (dest - src) == 0) { - scoped_restore_current_thread restore_thread; + scoped_restore_current_pspace_and_thread restore_pspace_thread; program_space *curr_pspace = current_program_space; for (inferior *inf : all_inferiors ()) diff --git a/gdb/infrun.c b/gdb/infrun.c index 9c4a07d..22de42c 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1020,8 +1020,6 @@ handle_vfork_child_exec_or_exit (int exec) } else { - struct program_space *pspace; - /* If this is a vfork child exiting, then the pspace and aspaces were shared with the parent. Since we're reporting the process exit, we'll be mourning all that is @@ -1037,18 +1035,12 @@ handle_vfork_child_exec_or_exit (int exec) scoped_restore restore_ptid = make_scoped_restore (&inferior_ptid, null_ptid); - /* This inferior is dead, so avoid giving the breakpoints - module the option to write through to it (cloning a - program space resets breakpoints). */ - inf->aspace = NULL; - inf->pspace = NULL; - pspace = new program_space (maybe_new_address_space ()); - set_current_program_space (pspace); + inf->pspace = new program_space (maybe_new_address_space ()); + inf->aspace = inf->pspace->aspace; + set_current_program_space (inf->pspace); inf->removable = 1; inf->symfile_flags = SYMFILE_NO_READ; - clone_program_space (pspace, vfork_parent->pspace); - inf->pspace = pspace; - inf->aspace = pspace->aspace; + clone_program_space (inf->pspace, vfork_parent->pspace); resume_parent = vfork_parent->pid; } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 3a97848..81500c2 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2020-01-24 Pedro Alves <palves@redhat.com> + + PR gdb/25410 + * gdb.multi/multi-re-run-1.c: New. + * gdb.multi/multi-re-run-2.c: New. + * gdb.multi/multi-re-run.exp: New. + 2020-01-24 Andrew Burgess <andrew.burgess@embecosm.com> PR gdb/23718 diff --git a/gdb/testsuite/gdb.multi/multi-re-run-1.c b/gdb/testsuite/gdb.multi/multi-re-run-1.c new file mode 100644 index 0000000..91b0dbc --- /dev/null +++ b/gdb/testsuite/gdb.multi/multi-re-run-1.c @@ -0,0 +1,61 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2020 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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <limits.h> +#include <string.h> +#include <pthread.h> + +int re_run_var_1 = 1; + +#define NUM_THREADS 1 + +__thread int tls_var = 1; + +static pthread_barrier_t barrier; + +static void * +thread_start (void *arg) +{ + pthread_barrier_wait (&barrier); + + while (1) + sleep (1); + return NULL; +} + +static void +all_started (void) +{ +} + +int +main (int argc, char ** argv) +{ + pthread_t thread; + int len; + + pthread_barrier_init (&barrier, NULL, NUM_THREADS + 1); + pthread_create (&thread, NULL, thread_start, NULL); + + pthread_barrier_wait (&barrier); + all_started (); + + return 0; +} diff --git a/gdb/testsuite/gdb.multi/multi-re-run-2.c b/gdb/testsuite/gdb.multi/multi-re-run-2.c new file mode 100644 index 0000000..6925e0c --- /dev/null +++ b/gdb/testsuite/gdb.multi/multi-re-run-2.c @@ -0,0 +1,61 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2020 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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <limits.h> +#include <string.h> +#include <pthread.h> + +int re_run_var_2 = 2; + +#define NUM_THREADS 1 + +__thread int tls_var = 1; + +static pthread_barrier_t barrier; + +static void * +thread_start (void *arg) +{ + pthread_barrier_wait (&barrier); + + while (1) + sleep (1); + return NULL; +} + +static void +all_started (void) +{ +} + +int +main (int argc, char ** argv) +{ + pthread_t thread; + int len; + + pthread_barrier_init (&barrier, NULL, NUM_THREADS + 1); + pthread_create (&thread, NULL, thread_start, NULL); + + pthread_barrier_wait (&barrier); + all_started (); + + return 0; +} diff --git a/gdb/testsuite/gdb.multi/multi-re-run.exp b/gdb/testsuite/gdb.multi/multi-re-run.exp new file mode 100644 index 0000000..93cd709 --- /dev/null +++ b/gdb/testsuite/gdb.multi/multi-re-run.exp @@ -0,0 +1,115 @@ +# Copyright 2020 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 loading two inferiors into GDB, and running one of them twice +# in a row. GDB used to have a bug that made it so that after an +# inferior exit, the current program space was left pointing to the +# wrong inferior's pspace, causing subsequent symbol lookups to +# misbehave, including failing to load libthread_db.so. See PR +# gdb/25410. + +# Build two executables, with different symbols. + +set exec1 "multi-re-run-1" +set srcfile1 multi-re-run-1.c +set binfile1 [standard_output_file ${exec1}] + +set exec2 "multi-re-run-2" +set srcfile2 multi-re-run-2.c +set binfile2 [standard_output_file ${exec2}] + +with_test_prefix "exec1" { + if { [prepare_for_testing "failed to prepare" ${exec1} "${srcfile1}" \ + [list pthreads debug]] } { + return -1 + } +} + +with_test_prefix "exec2" { + if { [prepare_for_testing "failed to prepare" ${exec2} "${srcfile2}" \ + [list pthreads debug]] } { + return -1 + } +} + +# Start two inferiors, leave one stopped, and run the other a couple +# times. RE_RUN_INF is the inferior that is re-run. + +proc test_re_run {re_run_inf} { + global binfile1 binfile2 + global inferior_exited_re + global gdb_prompt + + clean_restart ${binfile1} + + delete_breakpoints + + # Start another inferior. + gdb_test "add-inferior" "Added inferior 2.*" \ + "add empty inferior 2" + gdb_test "inferior 2" "Switching to inferior 2.*" \ + "switch to inferior 2" + gdb_load ${binfile2} + + if {$re_run_inf == 1} { + set steady_inf 2 + } else { + set steady_inf 1 + } + + gdb_test "inferior $steady_inf" "Switching to inferior $steady_inf.*" \ + "switch to steady inferior" + + # Run the steady inferior to a breakpoint, and let it stay stopped + # there. + if ![runto all_started message] then { + untested "setup failed" + return 0 + } + + gdb_test "inferior $re_run_inf" "Switching to inferior $re_run_inf.*" \ + "switch to re-run inferior" + + # Now run the RE_RUN_INF inferior a couple times. GDB used to + # have a bug that caused the second run to fail to load + # libthread_db.so. + foreach_with_prefix iter {1 2} { + delete_breakpoints + + if ![runto all_started message] { + return 0 + } + + # If a thread_stratum target fails to load, then TLS debugging + # fails too. + gdb_test "print tls_var" " = 1" + + gdb_continue_to_end "" continue 1 + + # In the original bug, after an inferior exit, GDB would leave + # the current program space pointing to the wrong inferior's + # pspace, and thus the wrong symbols were visible. + if {$re_run_inf == 1} { + gdb_test "print re_run_var_1" " = 1" + } else { + gdb_test "print re_run_var_2" " = 2" + } + } +} + +# For completeness, test re-running either inferior 1 or inferior 2. +foreach_with_prefix re_run_inf {1 2} { + test_re_run $re_run_inf +} diff --git a/gdb/thread.c b/gdb/thread.c index 001fdd4..302a49e 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -1429,10 +1429,7 @@ scoped_restore_current_thread::restore () && m_inf->pid != 0) switch_to_thread (m_thread); else - { - switch_to_no_thread (); - set_current_inferior (m_inf); - } + switch_to_inferior_no_thread (m_inf); /* The running state of the originally selected thread may have changed, so we have to recheck it here. */ |