diff options
author | Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> | 2020-04-21 17:24:03 +0200 |
---|---|---|
committer | Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> | 2020-04-21 17:24:03 +0200 |
commit | d43b7a2d5718f303a9e284f0d14219f05fbcfa17 (patch) | |
tree | a221395672b27c050693cec15b5be0e812c7762d /gdb/infrun.c | |
parent | bb2a1453479dfa2589f3b62853d4e1cf60825e98 (diff) | |
download | gdb-d43b7a2d5718f303a9e284f0d14219f05fbcfa17.zip gdb-d43b7a2d5718f303a9e284f0d14219f05fbcfa17.tar.gz gdb-d43b7a2d5718f303a9e284f0d14219f05fbcfa17.tar.bz2 |
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.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r-- | gdb/infrun.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index 5d60e64..0e1ba69 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1884,15 +1884,16 @@ displaced_step_fixup (thread_info *event_thread, enum gdb_signal signal) if (displaced->step_thread != event_thread) return 0; - displaced_step_reset_cleanup cleanup (displaced); - - displaced_step_restore (displaced, displaced->step_thread->ptid); - /* Fixup may need to read memory/registers. Switch to the thread that we're fixing up. Also, target_stopped_by_watchpoint checks - the current thread. */ + the current thread, and displaced_step_restore performs ptid-dependent + memory accesses using current_inferior() and current_top_target(). */ switch_to_thread (event_thread); + displaced_step_reset_cleanup cleanup (displaced); + + displaced_step_restore (displaced, displaced->step_thread->ptid); + /* Did the instruction complete successfully? */ if (signal == GDB_SIGNAL_TRAP && !(target_stopped_by_watchpoint () |