gdb/infrun: switch the context before 'displaced_step_restore'
authorTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Tue, 21 Apr 2020 15:24:03 +0000 (17:24 +0200)
committerTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Tue, 21 Apr 2020 15:24:03 +0000 (17:24 +0200)
commitd43b7a2d5718f303a9e284f0d14219f05fbcfa17
treea221395672b27c050693cec15b5be0e812c7762d
parentbb2a1453479dfa2589f3b62853d4e1cf60825e98
gdb/infrun: switch the context before 'displaced_step_restore'

In infrun.c's 'displaced_step_fixup', as part of the 'finish_step_over'
flow, switch to the eventing thread *before* calling
'displaced_step_restore', because down in the flow ptid-dependent
memory accesses are used via current_inferior() and current_top_target().

Without this patch, the problem is exposed with the scenario below:

   $ gdb -q
   (gdb) maint set target-non-stop on
   (gdb) file a.out
   Reading symbols from a.out...
   (gdb) set remote exec-file a.out
   (gdb) target extended-remote | gdbserver --once --multi -
   ...
   (gdb) add-inferior
   [New inferior 2]
   Added inferior 2 on connection 1 (extended-remote ...)
   (gdb) inferior 2
   [Switching to inferior 2 [<null>] (<noexec>)]
   (gdb) file a.out
   Reading symbols from a.out...
   (gdb) set remote exec-file a.out
   (gdb) run
   ...
   Cannot access memory at address 0x555555555042
   (gdb)

The problem is, down inside 'displaced_step_restore', GDB wants to
access the memory for inferior 2 because of an internal breakpoint.
However, the current inferior and inferior_ptid are out of sync.
While inferior_ptid correctly points to the process of inf 2 that was
just started, current_inferior points to inf 1.  Then, the attempt to
access the memory fails, because target_has_execution results in false
since inf 1 was not started.  I was not able to simplify the failing
scenario, but it shows the problem.

After this patch, we get

  ... same steps above...
  (gdb) run
  ...
  [Inferior 2 (process 28652) exited normally]
  (gdb)

Regression-tested on X86_64 Linux with `make check`s default board file
and also `--target_board=native-extended-gdbserver`.  In fact, the bug
fixed by this patch was exposed when using the native-extended-gdbserver
board file.

gdb/ChangeLog:
2020-04-21  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

* infrun.c (displaced_step_fixup): Switch to the event_thread
before calling displaced_step_restore, not after.

gdb/testsuite/ChangeLog:
2020-04-21  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

* gdb.multi/run-only-second-inf.c: New file.
* gdb.multi/run-only-second-inf.exp: New file.
gdb/ChangeLog
gdb/infrun.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.multi/run-only-second-inf.c [new file with mode: 0644]
gdb/testsuite/gdb.multi/run-only-second-inf.exp [new file with mode: 0644]