Home | History | Annotate | Line # | Download | only in gdb.multi
      1 # Copyright 2022-2024 Free Software Foundation, Inc.
      2 
      3 # This program is free software; you can redistribute it and/or modify
      4 # it under the terms of the GNU General Public License as published by
      5 # the Free Software Foundation; either version 3 of the License, or
      6 # (at your option) any later version.
      7 #
      8 # This program is distributed in the hope that it will be useful,
      9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11 # GNU General Public License for more details.
     12 #
     13 # You should have received a copy of the GNU General Public License
     14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15 
     16 # This test was introduced to reproduce a specific bug in GDBserver, where
     17 # attaching an inferior while another one was running would trigger a segfault
     18 # in GDBserver.  Reproducing the bug required specific circumstances:
     19 #
     20 #  - The first process must be far enough to have loaded its libc or
     21 #    libpthread (whatever triggers the loading of libthread_db), such that
     22 #    its proc->priv->thread_db is not nullptr
     23 #
     24 #  - However, its lwp must still be in the `!lwp->thread_known` state,
     25 #    meaning GDBserver hasn't asked libthread_db to compute the thread
     26 #    handle yet.  That means, GDB must not have refreshed the thread list
     27 #    yet, since that would cause the thread handles to be computed.  That
     28 #    means, no stopping on a breakpoint, since that causes a thread list
     29 #    update.  That's why the first inferior needs to be started with "run
     30 #    &".
     31 #
     32 #  - Attaching the second process would segfault GDBserver.
     33 #
     34 # All of this to say, if modifying this test, please keep in mind the original
     35 # intent.
     36 
     37 standard_testfile
     38 
     39 require can_spawn_for_attach
     40 
     41 if { [build_executable "failed to prepare" ${testfile} ${srcfile}] } {
     42     return
     43 }
     44 
     45 proc do_test {} {
     46     save_vars { ::GDBFLAGS } {
     47 	append ::GDBFLAGS " -ex \"maint set target-non-stop on\""
     48 	clean_restart $::binfile
     49     }
     50 
     51     gdb_test -no-prompt-anchor "run &"
     52     gdb_test "add-inferior" "Added inferior 2 on connection 1 .*"
     53     gdb_test "inferior 2" "Switching to inferior 2 .*"
     54 
     55     set spawn_id [spawn_wait_for_attach $::binfile]
     56     set pid [spawn_id_get_pid $spawn_id]
     57 
     58     # This call would crash GDBserver.
     59     gdb_attach $pid
     60 
     61     # Read a variable from the inferior, just to make sure the attach worked
     62     # fine.
     63     gdb_test "print global_var" " = 123"
     64 }
     65 
     66 do_test
     67