aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
authorTankut Baris Aktemur <tankut.baris.aktemur@intel.com>2020-04-21 17:24:03 +0200
committerTankut Baris Aktemur <tankut.baris.aktemur@intel.com>2020-04-21 17:24:03 +0200
commitd43b7a2d5718f303a9e284f0d14219f05fbcfa17 (patch)
treea221395672b27c050693cec15b5be0e812c7762d /gdb/infrun.c
parentbb2a1453479dfa2589f3b62853d4e1cf60825e98 (diff)
downloadgdb-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.c11
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 ()